diff options
author | Loic Bistuer <loic.bistuer@sixmedia.com> | 2013-07-31 12:52:11 +0700 |
---|---|---|
committer | Tim Graham <timograham@gmail.com> | 2013-08-04 09:14:18 -0400 |
commit | ebb3e50243448545c7314a1932a9067ddca5960b (patch) | |
tree | 5e4af9ef2bf3a9952e6410ef18366340b9523772 | |
parent | 61ecb5f48a4732f1471f858c64904ec1c4763925 (diff) | |
download | django-ebb3e50243448545c7314a1932a9067ddca5960b.tar.gz |
Introduced ModelAdmin.get_fields() and refactored get_fieldsets() to use it.
Refs #18681.
This also starts the deprecation of ModelAdmin.declared_fieldsets
-rw-r--r-- | django/contrib/admin/options.py | 60 | ||||
-rw-r--r-- | docs/internals/deprecation.txt | 2 | ||||
-rw-r--r-- | docs/ref/contrib/admin/index.txt | 8 | ||||
-rw-r--r-- | docs/releases/1.7.txt | 13 | ||||
-rw-r--r-- | tests/modeladmin/tests.py | 10 |
5 files changed, 80 insertions, 13 deletions
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index cb50d0e749..b475868598 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -2,6 +2,7 @@ from collections import OrderedDict import copy import operator from functools import partial, reduce, update_wrapper +import warnings from django import forms from django.conf import settings @@ -238,13 +239,49 @@ class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)): return db_field.formfield(**kwargs) - def _declared_fieldsets(self): + @property + def declared_fieldsets(self): + warnings.warn( + "ModelAdmin.declared_fieldsets is deprecated and " + "will be removed in Django 1.9.", + PendingDeprecationWarning, stacklevel=2 + ) + if self.fieldsets: return self.fieldsets elif self.fields: return [(None, {'fields': self.fields})] return None - declared_fieldsets = property(_declared_fieldsets) + + def get_fields(self, request, obj=None): + """ + Hook for specifying fields. + """ + return self.fields + + def get_fieldsets(self, request, obj=None): + """ + Hook for specifying fieldsets. + """ + # We access the property and check if it triggers a warning. + # If it does, then it's ours and we can safely ignore it, but if + # it doesn't then it has been overriden so we must warn about the + # deprecation. + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + declared_fieldsets = self.declared_fieldsets + if len(w) != 1 or not issubclass(w[0].category, PendingDeprecationWarning): + warnings.warn( + "ModelAdmin.declared_fieldsets is deprecated and " + "will be removed in Django 1.9.", + PendingDeprecationWarning + ) + if declared_fieldsets: + return declared_fieldsets + + if self.fieldsets: + return self.fieldsets + return [(None, {'fields': self.get_fields(request, obj)})] def get_ordering(self, request): """ @@ -478,13 +515,11 @@ class ModelAdmin(BaseModelAdmin): 'delete': self.has_delete_permission(request), } - def get_fieldsets(self, request, obj=None): - "Hook for specifying fieldsets for the add form." - if self.declared_fieldsets: - return self.declared_fieldsets + def get_fields(self, request, obj=None): + if self.fields: + return self.fields form = self.get_form(request, obj, fields=None) - fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj)) - return [(None, {'fields': fields})] + return list(form.base_fields) + list(self.get_readonly_fields(request, obj)) def get_form(self, request, obj=None, **kwargs): """ @@ -1657,12 +1692,11 @@ class InlineModelAdmin(BaseModelAdmin): return inlineformset_factory(self.parent_model, self.model, **defaults) - def get_fieldsets(self, request, obj=None): - if self.declared_fieldsets: - return self.declared_fieldsets + def get_fields(self, request, obj=None): + if self.fields: + return self.fields form = self.get_formset(request, obj, fields=None).form - fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj)) - return [(None, {'fields': fields})] + return list(form.base_fields) + list(self.get_readonly_fields(request, obj)) def get_queryset(self, request): queryset = super(InlineModelAdmin, self).get_queryset(request) diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index 9b0dbf8ffa..fe8b48a5a9 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -426,6 +426,8 @@ these changes. * ``django.utils.datastructures.SortedDict`` will be removed. Use :class:`collections.OrderedDict` from the Python standard library instead. +* ``ModelAdmin.declared_fieldsets`` will be removed. + 2.0 --- diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index 40ec514331..04dc52a3a1 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/docs/ref/contrib/admin/index.txt @@ -1218,6 +1218,14 @@ templates used by the :class:`ModelAdmin` views: changelist that will be linked to the change view, as described in the :attr:`ModelAdmin.list_display_links` section. +.. method:: ModelAdmin.get_fields(self, request, obj=None) + + .. versionadded:: 1.7 + + The ``get_fields`` method is given the ``HttpRequest`` and the ``obj`` + being edited (or ``None`` on an add form) and is expected to return a list + of fields, as described above in the :attr:`ModelAdmin.fields` section. + .. method:: ModelAdmin.get_fieldsets(self, request, obj=None) The ``get_fieldsets`` method is given the ``HttpRequest`` and the ``obj`` diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt index 91b932aff1..970f362949 100644 --- a/docs/releases/1.7.txt +++ b/docs/releases/1.7.txt @@ -113,6 +113,11 @@ Minor features * The admin's search fields can now be customized per-request thanks to the new :meth:`django.contrib.admin.ModelAdmin.get_search_fields` method. +* The :meth:`ModelAdmin.get_fields() + <django.contrib.admin.ModelAdmin.get_fields>` method may be overridden to + customize the value of :attr:`ModelAdmin.fields + <django.contrib.admin.ModelAdmin.fields>`. + Backwards incompatible changes in 1.7 ===================================== @@ -182,3 +187,11 @@ than simply ``myapp/models.py``, Django would look for :ref:`initial SQL data <initial-sql>` in ``myapp/models/sql/``. This bug has been fixed so that Django will search ``myapp/sql/`` as documented. The old location will continue to work until Django 1.9. + +``declared_fieldsets`` attribute on ``ModelAdmin.`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``ModelAdmin.declared_fieldsets`` was deprecated. Despite being a private API, +it will go through a regular deprecation path. This attribute was mostly used +by methods that bypassed ``ModelAdmin.get_fieldsets()`` but this was considered +a bug and has been addressed. diff --git a/tests/modeladmin/tests.py b/tests/modeladmin/tests.py index 616b0889b9..424588cf49 100644 --- a/tests/modeladmin/tests.py +++ b/tests/modeladmin/tests.py @@ -51,6 +51,12 @@ class ModelAdminTests(TestCase): self.assertEqual(list(ma.get_form(request).base_fields), ['name', 'bio', 'sign_date']) + self.assertEqual(list(ma.get_fields(request)), + ['name', 'bio', 'sign_date']) + + self.assertEqual(list(ma.get_fields(request, self.band)), + ['name', 'bio', 'sign_date']) + def test_default_fieldsets(self): # fieldsets_add and fieldsets_change should return a special data structure that # is used in the templates. They should generate the "right thing" whether we @@ -97,6 +103,10 @@ class ModelAdminTests(TestCase): ma = BandAdmin(Band, self.site) + self.assertEqual(list(ma.get_fields(request)), ['name']) + + self.assertEqual(list(ma.get_fields(request, self.band)), ['name']) + self.assertEqual(ma.get_fieldsets(request), [(None, {'fields': ['name']})]) |