=== modified file 'django/db/models/base.py'
|
|
|
|
| 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 | |
=== modified file 'django/db/models/fields/related.py'
|
|
|
|
| 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 | |