mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #13862 -- Added an ordering option to InlineModelAdmin and cleaned up documentation for it a bit. Thanks, Simon Meers, rasca and cogat.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14882 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		| @@ -67,6 +67,7 @@ class BaseModelAdmin(object): | ||||
|     prepopulated_fields = {} | ||||
|     formfield_overrides = {} | ||||
|     readonly_fields = () | ||||
|     ordering = None | ||||
|  | ||||
|     def __init__(self): | ||||
|         overrides = FORMFIELD_FOR_DBFIELD_DEFAULTS.copy() | ||||
| @@ -189,6 +190,18 @@ class BaseModelAdmin(object): | ||||
|     def get_readonly_fields(self, request, obj=None): | ||||
|         return self.readonly_fields | ||||
|  | ||||
|     def queryset(self, request): | ||||
|         """ | ||||
|         Returns a QuerySet of all model instances that can be edited by the | ||||
|         admin site. This is used by changelist_view. | ||||
|         """ | ||||
|         qs = self.model._default_manager.get_query_set() | ||||
|         # TODO: this should be handled by some parameter to the ChangeList. | ||||
|         ordering = self.ordering or () # otherwise we might try to *None, which is bad ;) | ||||
|         if ordering: | ||||
|             qs = qs.order_by(*ordering) | ||||
|         return qs | ||||
|  | ||||
| class ModelAdmin(BaseModelAdmin): | ||||
|     "Encapsulates all admin options and functionality for a given model." | ||||
|  | ||||
| @@ -202,7 +215,6 @@ class ModelAdmin(BaseModelAdmin): | ||||
|     date_hierarchy = None | ||||
|     save_as = False | ||||
|     save_on_top = False | ||||
|     ordering = None | ||||
|     inlines = [] | ||||
|  | ||||
|     # Custom templates (designed to be over-ridden in subclasses) | ||||
| @@ -325,18 +337,6 @@ class ModelAdmin(BaseModelAdmin): | ||||
|             'delete': self.has_delete_permission(request), | ||||
|         } | ||||
|  | ||||
|     def queryset(self, request): | ||||
|         """ | ||||
|         Returns a QuerySet of all model instances that can be edited by the | ||||
|         admin site. This is used by changelist_view. | ||||
|         """ | ||||
|         qs = self.model._default_manager.get_query_set() | ||||
|         # TODO: this should be handled by some parameter to the ChangeList. | ||||
|         ordering = self.ordering or () # otherwise we might try to *None, which is bad ;) | ||||
|         if ordering: | ||||
|             qs = qs.order_by(*ordering) | ||||
|         return qs | ||||
|  | ||||
|     def get_fieldsets(self, request, obj=None): | ||||
|         "Hook for specifying fieldsets for the add form." | ||||
|         if self.declared_fieldsets: | ||||
| @@ -1257,9 +1257,6 @@ class InlineModelAdmin(BaseModelAdmin): | ||||
|         fields = form.base_fields.keys() + list(self.get_readonly_fields(request, obj)) | ||||
|         return [(None, {'fields': fields})] | ||||
|  | ||||
|     def queryset(self, request): | ||||
|         return self.model._default_manager.all() | ||||
|  | ||||
| class StackedInline(InlineModelAdmin): | ||||
|     template = 'admin/edit_inline/stacked.html' | ||||
|  | ||||
|   | ||||
| @@ -180,7 +180,7 @@ subclass:: | ||||
|             .. versionadded:: 1.2 | ||||
|  | ||||
|             ``fields`` can contain values defined in | ||||
|             :attr:`ModelAdmin.readonly_fields` to be displayed as read-only. | ||||
|             :attr:`~ModelAdmin.readonly_fields` to be displayed as read-only. | ||||
|  | ||||
|         * ``classes`` | ||||
|             A list containing extra CSS classes to apply to the fieldset. | ||||
| @@ -504,8 +504,8 @@ subclass:: | ||||
|  | ||||
| .. attribute:: ModelAdmin.ordering | ||||
|  | ||||
|     Set ``ordering`` to specify how objects on the admin change list page | ||||
|     should be ordered. This should be a list or tuple in the same format as a | ||||
|     Set ``ordering`` to specify how lists of objects should be ordered in the | ||||
|     Django admin views. This should be a list or tuple in the same format as a | ||||
|     model's ``ordering`` parameter. | ||||
|  | ||||
|     If this isn't provided, the Django admin will use the model's default | ||||
| @@ -1089,8 +1089,36 @@ information. | ||||
| ``InlineModelAdmin`` options | ||||
| ----------------------------- | ||||
|  | ||||
| The ``InlineModelAdmin`` class is a subclass of ``ModelAdmin`` so it inherits | ||||
| all the same functionality as well as some of its own: | ||||
| ``InlineModelAdmin`` shares many of the same features as ``ModelAdmin``, and | ||||
| adds some of its own (the shared features are actually defined in the | ||||
| ``BaseModelAdmin`` superclass). The shared features are: | ||||
|  | ||||
| - :attr:`~InlineModelAdmin.form` | ||||
| - :attr:`~ModelAdmin.fieldsets` | ||||
| - :attr:`~ModelAdmin.fields` | ||||
| - :attr:`~ModelAdmin.exclude` | ||||
| - :attr:`~ModelAdmin.filter_horizontal` | ||||
| - :attr:`~ModelAdmin.filter_vertical` | ||||
| - :attr:`~ModelAdmin.prepopulated_fields` | ||||
| - :attr:`~ModelAdmin.radio_fields` | ||||
| - :attr:`~InlineModelAdmin.raw_id_fields` | ||||
|  | ||||
| .. versionadded:: 1.1 | ||||
|  | ||||
| - :meth:`~ModelAdmin.formfield_for_foreignkey` | ||||
| - :meth:`~ModelAdmin.formfield_for_manytomany` | ||||
|  | ||||
| .. versionadded:: 1.2 | ||||
|  | ||||
| - :attr:`~ModelAdmin.readonly_fields` | ||||
| - :attr:`~ModelAdmin.formfield_overrides` | ||||
|  | ||||
| .. versionadded:: 1.3 | ||||
|  | ||||
| - :attr:`~ModelAdmin.ordering` | ||||
| - :meth:`~ModelAdmin.queryset` | ||||
|  | ||||
| The ``InlineModelAdmin`` class adds: | ||||
|  | ||||
| .. attribute:: InlineModelAdmin.model | ||||
|  | ||||
| @@ -1118,7 +1146,6 @@ all the same functionality as well as some of its own: | ||||
|  | ||||
| .. attribute:: InlineModelAdmin.extra | ||||
|  | ||||
|  | ||||
|     This controls the number of extra forms the formset will display in | ||||
|     addition to the initial forms. See the | ||||
|     :doc:`formsets documentation </topics/forms/formsets>` for more | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| # coding: utf-8 | ||||
| from django.db import models | ||||
| from django.contrib import admin | ||||
|  | ||||
| class Band(models.Model): | ||||
|     name = models.CharField(max_length=100) | ||||
| @@ -8,3 +9,18 @@ class Band(models.Model): | ||||
|  | ||||
|     class Meta: | ||||
|         ordering = ('name',) | ||||
|  | ||||
| class Song(models.Model): | ||||
|     band = models.ForeignKey(Band) | ||||
|     name = models.CharField(max_length=100) | ||||
|     duration = models.IntegerField() | ||||
|  | ||||
|     class Meta: | ||||
|         ordering = ('name',) | ||||
|  | ||||
| class SongInlineDefaultOrdering(admin.StackedInline): | ||||
|     model = Song | ||||
|  | ||||
| class SongInlineNewOrdering(admin.StackedInline): | ||||
|     model = Song | ||||
|     ordering = ('duration', ) | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| from django.test import TestCase | ||||
| from django.contrib.admin.options import ModelAdmin | ||||
|  | ||||
| from models import Band | ||||
| from models import Band, Song, SongInlineDefaultOrdering, SongInlineNewOrdering | ||||
|  | ||||
| class TestAdminOrdering(TestCase): | ||||
|     """ | ||||
| @@ -37,3 +37,37 @@ class TestAdminOrdering(TestCase): | ||||
|         ma = BandAdmin(Band, None) | ||||
|         names = [b.name for b in ma.queryset(None)] | ||||
|         self.assertEqual([u'Radiohead', u'Van Halen', u'Aerosmith'], names) | ||||
|  | ||||
| class TestInlineModelAdminOrdering(TestCase): | ||||
|     """ | ||||
|     Let's make sure that InlineModelAdmin.queryset uses the ordering we define | ||||
|     in InlineModelAdmin. | ||||
|     """ | ||||
|  | ||||
|     def setUp(self): | ||||
|         b = Band(name='Aerosmith', bio='', rank=3) | ||||
|         b.save() | ||||
|         self.b = b | ||||
|         s1 = Song(band=b, name='Pink', duration=235) | ||||
|         s1.save() | ||||
|         s2 = Song(band=b, name='Dude (Looks Like a Lady)', duration=264) | ||||
|         s2.save() | ||||
|         s3 = Song(band=b, name='Jaded', duration=214) | ||||
|         s3.save() | ||||
|  | ||||
|     def test_default_ordering(self): | ||||
|         """ | ||||
|         The default ordering should be by name, as specified in the inner Meta | ||||
|         class. | ||||
|         """ | ||||
|         inline = SongInlineDefaultOrdering(self.b, None) | ||||
|         names = [s.name for s in inline.queryset(None)] | ||||
|         self.assertEqual([u'Dude (Looks Like a Lady)', u'Jaded', u'Pink'], names) | ||||
|  | ||||
|     def test_specified_ordering(self): | ||||
|         """ | ||||
|         Let's check with ordering set to something different than the default. | ||||
|         """ | ||||
|         inline = SongInlineNewOrdering(self.b, None) | ||||
|         names = [s.name for s in inline.queryset(None)] | ||||
|         self.assertEqual([u'Jaded', u'Pink', u'Dude (Looks Like a Lady)'], names) | ||||
		Reference in New Issue
	
	Block a user