Django

Code

Changeset 2260

Show
Ignore:
Timestamp:
02/03/06 18:07:03 (3 years ago)
Author:
adrian
Message:

magic-removal: Added support for QuerySet?.latest() and Manager.latest(), and updated unit tests.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/magic-removal/django/db/models/fields/related.py

    r2255 r2260  
    127127            manager.core_filters = {'%s__%s__exact' % (rel_field.name, instance_type._meta.pk.name): instance._get_pk_val()} 
    128128 
    129         # Prepare the manager. 
    130         # TODO: Fix this hack? 
    131         # We're setting manager.model here because manager._prepare() expects 
    132         # that manager.model is set. This is slightly hackish. 
    133129        manager.model = self.related.model 
    134         manager._prepare() 
    135130 
    136131        return manager 
     
    195190 
    196191        manager = RelatedManager() 
    197  
    198         # Prepare the manager. 
    199         # TODO: Fix this hack? 
    200         # We're setting manager.model here because manager._prepare() expects 
    201         # that manager.model is set. This is slightly hackish. 
    202192        manager.model = self.rel_model 
    203         manager._prepare() 
    204193 
    205194        return manager 
  • django/branches/magic-removal/django/db/models/manager.py

    r2252 r2260  
    1717            raise ValueError, "Model %s must specify a custom Manager, because it has a field named 'objects'" % name 
    1818        cls.add_to_class('objects', Manager()) 
    19         cls.objects._prepare() 
    2019 
    2120dispatcher.connect(ensure_default_manager, signal=signals.class_prepared) 
     
    3231        self.model = None 
    3332 
    34     def _prepare(self): 
    35         if self.model._meta.get_latest_by: 
    36             self.get_latest = self.__get_latest 
    37  
    3833    def contribute_to_class(self, model, name): 
    3934        # TODO: Use weakref because of possible memory leak / circular reference. 
    4035        self.model = model 
    41         dispatcher.connect(self._prepare, signal=signals.class_prepared, sender=model) 
    4236        setattr(model, name, ManagerDescriptor(self)) 
    4337        if not hasattr(model, '_default_manager') or self.creation_counter < model._default_manager.creation_counter: 
    4438            model._default_manager = self 
    45  
    46     def __get_latest(self, *args, **kwargs): 
    47         kwargs['order_by'] = ('-' + self.model._meta.get_latest_by,) 
    48         kwargs['limit'] = 1 
    49         return self.get_object(*args, **kwargs) 
    5039 
    5140    ####################### 
     
    9079        return self.get_query_set().iterator(*args, **kwargs) 
    9180 
     81    def latest(self, *args, **kwargs): 
     82        return self.get_query_set().latest(*args, **kwargs) 
     83 
    9284    def order_by(self, *args, **kwargs): 
    9385        return self.get_query_set().order_by(*args, **kwargs) 
  • django/branches/magic-removal/django/db/models/query.py

    r2257 r2260  
    162162        assert len(obj_list) == 1, "get() returned more than one %s -- it returned %s! Lookup parameters were %s" % (self.model._meta.object_name, len(obj_list), kwargs) 
    163163        return obj_list[0] 
     164 
     165    def latest(self, field_name=None): 
     166        """ 
     167        Returns the latest object, according to the model's 'get_latest_by' 
     168        option or optional given field_name. 
     169        """ 
     170        latest_by = field_name or self.model._meta.get_latest_by 
     171        assert bool(latest_by), "latest() requires either a field_name parameter or 'get_latest_by' in the model" 
     172        return self._clone(_limit=1, _order_by=('-'+latest_by,)).get() 
    164173 
    165174    def delete(self, *args, **kwargs): 
  • django/branches/magic-removal/tests/modeltests/get_latest/models.py

    r1754 r2260  
    1313class Article(models.Model): 
    1414    headline = models.CharField(maxlength=100) 
    15     pub_date = models.DateTimeField() 
     15    pub_date = models.DateField() 
     16    expire_date = models.DateField() 
    1617    class Meta: 
    1718        get_latest_by = 'pub_date' 
     
    2021        return self.headline 
    2122 
     23class Person(models.Model): 
     24    name = models.CharField(maxlength=30) 
     25    birthday = models.DateField() 
     26 
     27    # Note that this model doesn't have "get_latest_by" set. 
     28 
     29    def __repr__(self): 
     30        return self.name 
     31 
    2232API_TESTS = """ 
    2333# Because no Articles exist yet, get_latest() raises ArticleDoesNotExist. 
    24 >>> Article.objects.get_latest() 
     34>>> Article.objects.latest() 
    2535Traceback (most recent call last): 
    2636    ... 
    27 DoesNotExist: Article does not exist for {'order_by': ('-pub_date',), 'limit': 1} 
     37DoesNotExist: Article does not exist for ... 
    2838 
    2939# Create a couple of Articles. 
    3040>>> from datetime import datetime 
    31 >>> a1 = Article(id=None, headline='Article 1', pub_date=datetime(2005, 7, 26)) 
     41>>> a1 = Article(headline='Article 1', pub_date=datetime(2005, 7, 26), expire_date=datetime(2005, 9, 1)) 
    3242>>> a1.save() 
    33 >>> a2 = Article(id=None, headline='Article 2', pub_date=datetime(2005, 7, 27)) 
     43>>> a2 = Article(headline='Article 2', pub_date=datetime(2005, 7, 27), expire_date=datetime(2005, 7, 28)) 
    3444>>> a2.save() 
    35 >>> a3 = Article(id=None, headline='Article 3', pub_date=datetime(2005, 7, 27)) 
     45>>> a3 = Article(headline='Article 3', pub_date=datetime(2005, 7, 27), expire_date=datetime(2005, 8, 27)) 
    3646>>> a3.save() 
    37 >>> a4 = Article(id=None, headline='Article 4', pub_date=datetime(2005, 7, 28)) 
     47>>> a4 = Article(headline='Article 4', pub_date=datetime(2005, 7, 28), expire_date=datetime(2005, 7, 30)) 
    3848>>> a4.save() 
    3949 
    4050# Get the latest Article. 
    41 >>> Article.objects.get_latest() 
     51>>> Article.objects.latest() 
    4252Article 4 
     53 
     54# Get the latest Article that matches certain filters. 
     55>>> Article.objects.filter(pub_date__lt=datetime(2005, 7, 27)).latest() 
     56Article 1 
     57 
     58# Pass a custom field name to latest() to change the field that's used to 
     59# determine the latest object. 
     60>>> Article.objects.latest('expire_date') 
     61Article 1 
     62 
     63>>> Article.objects.filter(pub_date__gt=datetime(2005, 7, 26)).latest('expire_date') 
     64Article 3 
     65 
     66# You can still use latest() with a model that doesn't have "get_latest_by" 
     67# set -- just pass in the field name manually. 
     68>>> p1 = Person(name='Ralph', birthday=datetime(1950, 1, 1)) 
     69>>> p1.save() 
     70>>> p2 = Person(name='Stephanie', birthday=datetime(1960, 2, 3)) 
     71>>> p2.save() 
     72>>> Person.objects.latest() 
     73Traceback (most recent call last): 
     74    ... 
     75AssertionError: latest() requires either a field_name parameter or 'get_latest_by' in the model 
     76 
     77>>> Person.objects.latest('birthday') 
     78Stephanie 
    4379"""