Ticket #13862: inline_queryset_ordering_2.diff

File inline_queryset_ordering_2.diff, 6.3 KB (added by rasca, 13 years ago)

added docs and tests

  • django/contrib/admin/options.py

    diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
    index ffc6e79..1a4ccc4 100644
    a b class BaseModelAdmin(object):  
    6767    prepopulated_fields = {}
    6868    formfield_overrides = {}
    6969    readonly_fields = ()
     70    ordering = None
    7071
    7172    def __init__(self):
    7273        overrides = FORMFIELD_FOR_DBFIELD_DEFAULTS.copy()
    class BaseModelAdmin(object):  
    189190    def get_readonly_fields(self, request, obj=None):
    190191        return self.readonly_fields
    191192
     193    def queryset(self, request):
     194        """
     195        Returns a QuerySet of all model instances that can be edited by the
     196        admin site. This is used by changelist_view.
     197        """
     198        qs = self.model._default_manager.get_query_set()
     199        # TODO: this should be handled by some parameter to the ChangeList.
     200        ordering = self.ordering or () # otherwise we might try to *None, which is bad ;)
     201        if ordering:
     202            qs = qs.order_by(*ordering)
     203        return qs
     204
    192205class ModelAdmin(BaseModelAdmin):
    193206    "Encapsulates all admin options and functionality for a given model."
    194207
    class ModelAdmin(BaseModelAdmin):  
    202215    date_hierarchy = None
    203216    save_as = False
    204217    save_on_top = False
    205     ordering = None
    206218    inlines = []
    207219
    208220    # Custom templates (designed to be over-ridden in subclasses)
    class ModelAdmin(BaseModelAdmin):  
    325337            'delete': self.has_delete_permission(request),
    326338        }
    327339
    328     def queryset(self, request):
    329         """
    330         Returns a QuerySet of all model instances that can be edited by the
    331         admin site. This is used by changelist_view.
    332         """
    333         qs = self.model._default_manager.get_query_set()
    334         # TODO: this should be handled by some parameter to the ChangeList.
    335         ordering = self.ordering or () # otherwise we might try to *None, which is bad ;)
    336         if ordering:
    337             qs = qs.order_by(*ordering)
    338         return qs
    339 
    340340    def get_fieldsets(self, request, obj=None):
    341341        "Hook for specifying fieldsets for the add form."
    342342        if self.declared_fieldsets:
    class InlineModelAdmin(BaseModelAdmin):  
    12791279        fields = form.base_fields.keys() + list(self.get_readonly_fields(request, obj))
    12801280        return [(None, {'fields': fields})]
    12811281
    1282     def queryset(self, request):
    1283         return self.model._default_manager.all()
    1284 
    12851282class StackedInline(InlineModelAdmin):
    12861283    template = 'admin/edit_inline/stacked.html'
    12871284
  • docs/ref/contrib/admin/index.txt

    diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
    index ac517e8..8e64ec7 100644
    a b all the same functionality as well as some of its own:  
    10931093    doesn't directly correlate to the number of objects, but can if the value
    10941094    is small enough. See :ref:`model-formsets-max-num` for more information.
    10951095
     1096.. attribute:: InlineModelAdmin.ordering
     1097
     1098    Set ``ordering`` to specify how inlines on the admin change form page should
     1099    be ordered. This should be a list or tuple in the same format as a model's
     1100    ``ordering`` parameter.
     1101
     1102    If this isn't provided, the Django admin will use the model's default ordering.
     1103
     1104    .. admonition:: Note
     1105
     1106        Django will only honor the first element in the list/tuple; any others
     1107        will be ignored.
     1108
    10961109.. attribute:: InlineModelAdmin.raw_id_fields
    10971110
    10981111    By default, Django's admin uses a select-box interface (<select>) for
  • tests/regressiontests/admin_ordering/models.py

    diff --git a/tests/regressiontests/admin_ordering/models.py b/tests/regressiontests/admin_ordering/models.py
    index ad63685..fb76677 100644
    a b  
    11# coding: utf-8
    22from django.db import models
     3from django.contrib import admin
    34
    45class Band(models.Model):
    56    name = models.CharField(max_length=100)
    class Band(models.Model):  
    89
    910    class Meta:
    1011        ordering = ('name',)
     12
     13class Song(models.Model):
     14    band = models.ForeignKey(Band)
     15    name = models.CharField(max_length=100)
     16    duration = models.IntegerField()
     17
     18    class Meta:
     19        ordering = ('name',)
     20
     21class SongInlineDefaultOrdering(admin.StackedInline):
     22    model = Song
     23
     24class SongInlineNewOrdering(admin.StackedInline):
     25    model = Song
     26    ordering = ('duration', )
  • tests/regressiontests/admin_ordering/tests.py

    diff --git a/tests/regressiontests/admin_ordering/tests.py b/tests/regressiontests/admin_ordering/tests.py
    index f63f202..1b91ac0 100644
    a b  
    11from django.test import TestCase
    22from django.contrib.admin.options import ModelAdmin
    33
    4 from models import Band
     4from models import Band, Song, SongInlineDefaultOrdering, SongInlineNewOrdering
    55
    66class TestAdminOrdering(TestCase):
    77    """
    class TestAdminOrdering(TestCase):  
    3737        ma = BandAdmin(Band, None)
    3838        names = [b.name for b in ma.queryset(None)]
    3939        self.assertEqual([u'Radiohead', u'Van Halen', u'Aerosmith'], names)
     40
     41class TestInlineModelAdminOrdering(TestCase):
     42    """
     43    Let's make sure that InlineModelAdmin.queryset uses the ordering we define
     44    in InlineModelAdmin.
     45    """
     46
     47    def setUp(self):
     48        b = Band(name='Aerosmith', bio='', rank=3)
     49        b.save()
     50        self.b = b
     51        s1 = Song(band=b, name='Pink', duration=235)
     52        s1.save()
     53        s2 = Song(band=b, name='Dude (Looks Like a Lady)', duration=264)
     54        s2.save()
     55        s3 = Song(band=b, name='Jaded', duration=214)
     56        s3.save()
     57
     58    def test_default_ordering(self):
     59        """
     60        The default ordering should be by name, as specified in the inner Meta
     61        class.
     62        """
     63        inline = SongInlineDefaultOrdering(self.b, None)
     64        names = [s.name for s in inline.queryset(None)]
     65        self.assertEqual([u'Dude (Looks Like a Lady)', u'Jaded', u'Pink'], names)
     66
     67    def test_specified_ordering(self):
     68        """
     69        Let's check with ordering set to something different than the default.
     70        """
     71        inline = SongInlineNewOrdering(self.b, None)
     72        names = [s.name for s in inline.queryset(None)]
     73        self.assertEqual([u'Jaded', u'Pink', u'Dude (Looks Like a Lady)'], names)
Back to Top