summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoic Bistuer <loic.bistuer@sixmedia.com>2013-07-31 12:52:11 +0700
committerTim Graham <timograham@gmail.com>2013-08-04 09:14:18 -0400
commitebb3e50243448545c7314a1932a9067ddca5960b (patch)
tree5e4af9ef2bf3a9952e6410ef18366340b9523772
parent61ecb5f48a4732f1471f858c64904ec1c4763925 (diff)
downloaddjango-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.py60
-rw-r--r--docs/internals/deprecation.txt2
-rw-r--r--docs/ref/contrib/admin/index.txt8
-rw-r--r--docs/releases/1.7.txt13
-rw-r--r--tests/modeladmin/tests.py10
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']})])