Ticket #17: patch
| File patch, 4.0 kB (added by ferringb@gmail.com, 1 year ago) |
|---|
-
django/db/models/base.py
old new 14 14 from django.utils.functional import curry 15 15 from django.conf import settings 16 16 from itertools import izip 17 from weakref import WeakValueDictionary 17 18 import types 18 19 import sys 19 20 import os … … 71 72 # registered version. 72 73 return get_model(new_class._meta.app_label, name, False) 73 74 75 def __call__(cls, *args, **kwargs): 76 if cls._meta.has_auto_field: 77 key = cls._get_cache_key(args, kwargs) 78 if key is not None: 79 obj = cls.__instance_cache__.get(key) 80 if obj is None: 81 obj = super(ModelBase, cls).__call__(*args, **kwargs) 82 cls.__instance_cache__[key] = obj 83 else: 84 obj = super(ModelBase, cls).__call__(*args, **kwargs) 85 else: 86 obj = super(ModelBase, cls).__call__(*args, **kwargs) 87 return obj 88 89 74 90 class Model(object): 75 91 __metaclass__ = ModelBase 76 92 … … 89 105 def __ne__(self, other): 90 106 return not self.__eq__(other) 91 107 108 def _get_cache_key(cls, args, kwargs): 109 # this should be calculated *once*, but isn't atm 110 pk_position = cls._meta.fields.index(cls._meta.pk) 111 if len(args) > pk_position: 112 return args[pk_position] 113 pk = cls._meta.pk 114 if pk.name in kwargs: 115 return kwargs[pk.name] 116 elif pk.attname in kwargs: 117 return kwargs[pk.attname] 118 return None 119 _get_cache_key = classmethod(_get_cache_key) 120 121 def get_cached_instance(cls, id): 122 return cls.__instance_cache__.get(id) 123 get_cached_instance = classmethod(get_cached_instance) 124 92 125 def __init__(self, *args, **kwargs): 93 126 dispatcher.send(signal=signals.pre_init, sender=self.__class__, args=args, kwargs=kwargs) 94 127 # there is a rather weird disparity here; if kwargs, it's set, then args overrides it. … … 185 218 if hasattr(cls, 'get_absolute_url'): 186 219 cls.get_absolute_url = curry(get_absolute_url, opts, cls.get_absolute_url) 187 220 221 cls.__instance_cache__ = WeakValueDictionary() 222 188 223 dispatcher.send(signal=signals.class_prepared, sender=cls) 189 224 190 225 _prepare = classmethod(_prepare) … … 241 276 setattr(self, self._meta.pk.attname, backend.get_last_insert_id(cursor, self._meta.db_table, self._meta.pk.column)) 242 277 transaction.commit_unless_managed() 243 278 279 # if we're a new instance that hasn't been written in; save ourself. 280 if self._meta.has_auto_field: 281 self.__instance_cache__.setdefault(pk_val, self) 282 244 283 # Run any post-save hooks. 245 284 dispatcher.send(signal=signals.post_save, sender=self.__class__, instance=self) 246 285 -
django/db/models/fields/related.py
old new 163 163 if self.field.null: 164 164 return None 165 165 raise self.field.rel.to.DoesNotExist 166 other_field = self.field.rel.get_related_field() 167 if other_field.rel: 168 params = {'%s__pk' % self.field.rel.field_name: val} 169 else: 170 params = {'%s__exact' % self.field.rel.field_name: val} 171 rel_obj = self.field.rel.to._default_manager.get(**params) 166 rel_obj = self.field.rel.to.get_cached_instance(val) 167 if rel_obj is None: 168 other_field = self.field.rel.get_related_field() 169 if other_field.rel: 170 params = {'%s__pk' % self.field.rel.field_name: val} 171 else: 172 params = {'%s__exact' % self.field.rel.field_name: val} 173 rel_obj = self.field.rel.to._default_manager.get(**params) 172 174 setattr(instance, cache_name, rel_obj) 173 175 return rel_obj 174 176
