Django

Code

Ticket #3369: patch_2.diff

File patch_2.diff, 5.5 kB (added by wbyoung@mcdonogh.org, 2 years ago)
  • django/db/models/manager.py

    old new  
    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

    old new  
    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

    old new  
    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

    old new  
    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

    old new  
    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