Ticket #3369: patch_2.diff

File patch_2.diff, 5.5 KB (added by wbyoung@…, 8 years ago)
  • django/db/models/manager.py

     
    101101
    102102    def select_related(self, *args, **kwargs):
    103103        return self.get_query_set().select_related(*args, **kwargs)
     104   
     105    def auto_cache(self, *args, **kwargs):
     106        return self.get_query_set().auto_cache(*args, **kwargs)
    104107
    105108    def values(self, *args, **kwargs):
    106109        return self.get_query_set().values(*args, **kwargs)
  • django/db/models/fields/related.py

     
    135135        # Set the value of the related field
    136136        setattr(value, self.related.field.rel.get_related_field().attname, instance)
    137137
    138         # Clear the cache, if it exists
     138        # Update the cache, if it exists
    139139        try:
    140             delattr(value, self.related.field.get_cache_name())
     140            setattr(value, self.related.field.get_cache_name(), value)
    141141        except AttributeError:
    142142            pass
    143143
     
    182182            val = None
    183183        setattr(instance, self.field.attname, val)
    184184
    185         # Clear the cache, if it exists
     185        # Update the cache, if it exists
    186186        try:
    187             delattr(instance, self.field.get_cache_name())
     187            setattr(instance, self.field.get_cache_name(), value)
    188188        except AttributeError:
    189189            pass
    190190
     
    210210
    211211        class RelatedManager(superclass):
    212212            def get_query_set(self):
    213                 return superclass.get_query_set(self).filter(**(self.core_filters))
     213                return superclass.get_query_set(self).filter(**(self.core_filters)).auto_cache(**self.core_cache)
    214214
    215215            def add(self, *objs):
    216216                for obj in objs:
     
    245245
    246246        manager = RelatedManager()
    247247        manager.core_filters = {'%s__pk' % rel_field.name: getattr(instance, rel_field.rel.get_related_field().attname)}
     248        manager.core_cache = { rel_field.name: instance }
    248249        manager.model = self.related.model
    249250
    250251        return manager
  • django/db/models/query.py

     
    9191        self._tables = []            # List of extra tables to use.
    9292        self._offset = None          # OFFSET clause.
    9393        self._limit = None           # LIMIT clause.
     94        self._auto_cache = {}        # Dictionary of items to automatically cache on the fetched objects.
    9495        self._result_cache = None
    9596
    9697    ########################
     
    192193                    obj = self.model(*row[:index_end])
    193194                for i, k in enumerate(extra_select):
    194195                    setattr(obj, k[0], row[index_end+i])
     196                # auto cache items
     197                for key in self._auto_cache:
     198                  setattr(obj, key, self._auto_cache[key])
    195199                yield obj
    196200
    197201    def count(self):
     
    386390    def distinct(self, true_or_false=True):
    387391        "Returns a new QuerySet instance with '_distinct' modified."
    388392        return self._clone(_distinct=true_or_false)
     393   
     394    def auto_cache(self, **kwargs):
     395        """"Returns a new QuerySet instance with _auto_cache modified.
     396        This is not available publicly.  It is used to automatically cache
     397        the reverse foreign key assocaiation when getting an object through
     398        a FOO_set. """
     399        return self._clone(_auto_cache=kwargs)
    389400
    390401    def extra(self, select=None, where=None, params=None, tables=None):
    391402        assert self._limit is None and self._offset is None, \
     
    416427        c._tables = self._tables[:]
    417428        c._offset = self._offset
    418429        c._limit = self._limit
     430        c._auto_cache = self._auto_cache.copy()
    419431        c.__dict__.update(kwargs)
    420432        return c
    421433
  • tests/modeltests/many_to_one/models.py

     
    245245>>> Reporter.objects.filter(article__reporter=r).distinct()
    246246[<Reporter: John Smith>]
    247247
     248# Automatic caching
     249>>> r_ac = Reporter.objects.all()[0]
     250>>> r_ac
     251<Reporter: John Smith>
     252>>> a_ac = r_ac.article_set.all()[0]
     253>>> a_ac
     254<Article: John's second story>
     255>>> a_ac.reporter is r_ac
     256True
     257
    248258# If you delete a reporter, his articles will be deleted.
    249259>>> Article.objects.all()
    250260[<Article: John's second story>, <Article: Paul's story>, <Article: This is a test>, <Article: This is a test>, <Article: This is a test>]
  • docs/db-api.txt

     
    14461446    b.entry_set.filter(headline__contains='Lennon')
    14471447    b.entry_set.count()
    14481448
     1449Note that the reverse association from the foreign key is automatically cached
     1450when retrieving objects through this ``Manager``.
     1451
     1452Example::
     1453    b = Blog.objects.get(id=1)
     1454    for entry in b.entry_set.all():
     1455        entry.blog # No database access required.
     1456
    14491457You can override the ``FOO_set`` name by setting the ``related_name``
    14501458parameter in the ``ForeignKey()`` definition. For example, if the ``Entry``
    14511459model was altered to ``blog = ForeignKey(Blog, related_name='entries')``, the
Back to Top