Django

Code

Changeset 9211

Show
Ignore:
Timestamp:
10/08/08 09:47:01 (3 months ago)
Author:
kmtracey
Message:

Fixed #9053 -- Allowed for sorting of callable and ModelAdmin? methods specified in list_display (added in r8352). Previously attempting to sort on the former would raise an exception and the latter simply didn't sort. Also added tests for this function. Thanks rgl and jenan.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/contrib/admin/views/main.py

    r9080 r9211  
    158158                    # that allows sorting. 
    159159                    try: 
    160                         attr = getattr(self.model, field_name) 
     160                        if callable(field_name): 
     161                            attr = field_name 
     162                        elif hasattr(self.model_admin, field_name): 
     163                            attr = getattr(self.model_admin, field_name) 
     164                        else: 
     165                            attr = getattr(self.model, field_name) 
    161166                        order_field = attr.admin_order_field 
    162167                    except AttributeError: 
  • django/trunk/tests/regressiontests/admin_views/fixtures/admin-views-users.xml

    r7967 r9211  
    7575    </object> 
    7676    <object pk="1" model="admin_views.article"> 
    77         <field type="TextField" name="content">&lt;p&gt;test content&lt;/p&gt;</field> 
     77        <field type="TextField" name="content">&lt;p&gt;Middle content&lt;/p&gt;</field> 
    7878        <field type="DateTimeField" name="date">2008-03-18 11:54:58</field> 
    7979        <field to="admin_views.section" name="section" rel="ManyToOneRel">1</field> 
    8080    </object> 
     81    <object pk="2" model="admin_views.article"> 
     82        <field type="TextField" name="content">&lt;p&gt;Oldest content&lt;/p&gt;</field> 
     83        <field type="DateTimeField" name="date">2000-03-18 11:54:58</field> 
     84        <field to="admin_views.section" name="section" rel="ManyToOneRel">1</field> 
     85    </object> 
     86    <object pk="3" model="admin_views.article"> 
     87        <field type="TextField" name="content">&lt;p&gt;Newest content&lt;/p&gt;</field> 
     88        <field type="DateTimeField" name="date">2009-03-18 11:54:58</field> 
     89        <field to="admin_views.section" name="section" rel="ManyToOneRel">1</field> 
     90    </object> 
     91 
     92 
    8193</django-objects> 
  • django/trunk/tests/regressiontests/admin_views/models.py

    r8273 r9211  
    2020    def __unicode__(self): 
    2121        return self.title 
     22     
     23    def model_year(self): 
     24        return self.date.year 
     25    model_year.admin_order_field = 'date' 
     26 
     27def callable_year(dt_value): 
     28    return dt_value.year 
     29callable_year.admin_order_field = 'date' 
    2230 
    2331class ArticleInline(admin.TabularInline): 
     
    2533 
    2634class ArticleAdmin(admin.ModelAdmin): 
    27     list_display = ('content', 'date'
     35    list_display = ('content', 'date', callable_year, 'model_year', 'modeladmin_year'
    2836    list_filter = ('date',) 
    2937 
     
    3543            } 
    3644        ) 
     45         
     46    def modeladmin_year(self, obj): 
     47        return obj.date.year 
     48    modeladmin_year.admin_order_field = 'date' 
    3749 
    3850class CustomArticle(models.Model): 
  • django/trunk/tests/regressiontests/admin_views/tests.py

    r8877 r9211  
    7272            "name": u"Test section", 
    7373            # inline data 
    74             "article_set-TOTAL_FORMS": u"4", 
    75             "article_set-INITIAL_FORMS": u"1", 
     74            "article_set-TOTAL_FORMS": u"6", 
     75            "article_set-INITIAL_FORMS": u"3", 
    7676            "article_set-0-id": u"1", 
    7777            # there is no title in database, give one here or formset 
    7878            # will fail. 
    7979            "article_set-0-title": u"Need a title.", 
    80             "article_set-0-content": u"&lt;p&gt;test content&lt;/p&gt;", 
     80            "article_set-0-content": u"&lt;p&gt;Middle content&lt;/p&gt;", 
    8181            "article_set-0-date_0": u"2008-03-18", 
    8282            "article_set-0-date_1": u"11:54:58", 
    83             "article_set-1-id": u"", 
    84             "article_set-1-title": u"", 
    85             "article_set-1-content": u"", 
    86             "article_set-1-date_0": u"", 
    87             "article_set-1-date_1": u"", 
    88             "article_set-2-id": u"", 
    89             "article_set-2-title": u"", 
    90             "article_set-2-content": u"", 
    91             "article_set-2-date_0": u"", 
    92             "article_set-2-date_1": u"", 
     83            "article_set-1-id": u"2", 
     84            "article_set-1-title": u"Need a title.", 
     85            "article_set-1-content": u"&lt;p&gt;Oldest content&lt;/p&gt;", 
     86            "article_set-1-date_0": u"2000-03-18", 
     87            "article_set-1-date_1": u"11:54:58", 
     88            "article_set-2-id": u"3", 
     89            "article_set-2-title": u"Need a title.", 
     90            "article_set-2-content": u"&lt;p&gt;Newest content&lt;/p&gt;", 
     91            "article_set-2-date_0": u"2009-03-18", 
     92            "article_set-2-date_1": u"11:54:58", 
    9393            "article_set-3-id": u"", 
    9494            "article_set-3-title": u"", 
     
    9696            "article_set-3-date_0": u"", 
    9797            "article_set-3-date_1": u"", 
     98            "article_set-4-id": u"", 
     99            "article_set-4-title": u"", 
     100            "article_set-4-content": u"", 
     101            "article_set-4-date_0": u"", 
     102            "article_set-4-date_1": u"", 
     103            "article_set-5-id": u"", 
     104            "article_set-5-title": u"", 
     105            "article_set-5-content": u"", 
     106            "article_set-5-date_0": u"", 
     107            "article_set-5-date_1": u"", 
    98108        } 
    99109        response = self.client.post('/test_admin/admin/admin_views/section/1/', post_data) 
    100110        self.failUnlessEqual(response.status_code, 302) # redirect somewhere 
    101111 
     112    def testChangeListSortingCallable(self): 
     113        """ 
     114        Ensure we can sort on a list_display field that is a callable  
     115        (column 2 is callable_year in ArticleAdmin) 
     116        """ 
     117        response = self.client.get('/test_admin/admin/admin_views/article/', {'ot': 'asc', 'o': 2}) 
     118        self.failUnlessEqual(response.status_code, 200) 
     119        self.failUnless( 
     120            response.content.index('Oldest content') < response.content.index('Middle content') and 
     121            response.content.index('Middle content') < response.content.index('Newest content'), 
     122            "Results of sorting on callable are out of order." 
     123        ) 
     124     
     125    def testChangeListSortingModel(self): 
     126        """ 
     127        Ensure we can sort on a list_display field that is a Model method  
     128        (colunn 3 is 'model_year' in ArticleAdmin) 
     129        """ 
     130        response = self.client.get('/test_admin/admin/admin_views/article/', {'ot': 'dsc', 'o': 3}) 
     131        self.failUnlessEqual(response.status_code, 200) 
     132        self.failUnless( 
     133            response.content.index('Newest content') < response.content.index('Middle content') and 
     134            response.content.index('Middle content') < response.content.index('Oldest content'), 
     135            "Results of sorting on Model method are out of order." 
     136        ) 
     137     
     138    def testChangeListSortingModelAdmin(self): 
     139        """ 
     140        Ensure we can sort on a list_display field that is a ModelAdmin method  
     141        (colunn 4 is 'modeladmin_year' in ArticleAdmin) 
     142        """ 
     143        response = self.client.get('/test_admin/admin/admin_views/article/', {'ot': 'asc', 'o': 4}) 
     144        self.failUnlessEqual(response.status_code, 200) 
     145        self.failUnless( 
     146            response.content.index('Oldest content') < response.content.index('Middle content') and  
     147            response.content.index('Middle content') < response.content.index('Newest content'), 
     148            "Results of sorting on ModelAdmin method are out of order." 
     149        ) 
     150     
    102151def get_perm(Model, perm): 
    103152    """Return the permission object, for the Model""" 
     
    253302        post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict) 
    254303        self.failUnlessEqual(post.status_code, 403) 
    255         self.failUnlessEqual(Article.objects.all().count(), 1
     304        self.failUnlessEqual(Article.objects.all().count(), 3
    256305        self.client.get('/test_admin/admin/logout/') 
    257306 
     
    261310        post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict) 
    262311        self.assertRedirects(post, '/test_admin/admin/') 
    263         self.failUnlessEqual(Article.objects.all().count(), 2
     312        self.failUnlessEqual(Article.objects.all().count(), 4
    264313        self.client.get('/test_admin/admin/logout/') 
    265314 
     
    269318        post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict) 
    270319        self.assertRedirects(post, '/test_admin/admin/admin_views/article/') 
    271         self.failUnlessEqual(Article.objects.all().count(), 3
     320        self.failUnlessEqual(Article.objects.all().count(), 5
    272321        self.client.get('/test_admin/admin/logout/') 
    273322 
     
    393442        post = self.client.post('/test_admin/admin/admin_views/article/1/delete/', delete_dict) 
    394443        self.failUnlessEqual(post.status_code, 403) 
    395         self.failUnlessEqual(Article.objects.all().count(), 1
     444        self.failUnlessEqual(Article.objects.all().count(), 3
    396445        self.client.get('/test_admin/admin/logout/') 
    397446 
     
    407456        post = self.client.post('/test_admin/admin/admin_views/article/1/delete/', delete_dict) 
    408457        self.assertRedirects(post, '/test_admin/admin/') 
    409         self.failUnlessEqual(Article.objects.all().count(), 0
     458        self.failUnlessEqual(Article.objects.all().count(), 2
    410459        self.client.get('/test_admin/admin/logout/') 
    411460