Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Introduced ModelAdmin.get_fields() and refactored get_fieldsets() to …

…use it.

Refs #18681.

This also starts the deprecation of ModelAdmin.declared_fieldsets
  • Loading branch information...
commit ebb3e50243448545c7314a1932a9067ddca5960b 1 parent 61ecb5f
Loic Bistuer authored July 31, 2013 timgraham committed August 04, 2013
60  django/contrib/admin/options.py
@@ -2,6 +2,7 @@
2 2
 import copy
3 3
 import operator
4 4
 from functools import partial, reduce, update_wrapper
  5
+import warnings
5 6
 
6 7
 from django import forms
7 8
 from django.conf import settings
@@ -238,13 +239,49 @@ def formfield_for_manytomany(self, db_field, request=None, **kwargs):
238 239
 
239 240
         return db_field.formfield(**kwargs)
240 241
 
241  
-    def _declared_fieldsets(self):
  242
+    @property
  243
+    def declared_fieldsets(self):
  244
+        warnings.warn(
  245
+            "ModelAdmin.declared_fieldsets is deprecated and "
  246
+            "will be removed in Django 1.9.",
  247
+            PendingDeprecationWarning, stacklevel=2
  248
+        )
  249
+
242 250
         if self.fieldsets:
243 251
             return self.fieldsets
244 252
         elif self.fields:
245 253
             return [(None, {'fields': self.fields})]
246 254
         return None
247  
-    declared_fieldsets = property(_declared_fieldsets)
  255
+
  256
+    def get_fields(self, request, obj=None):
  257
+        """
  258
+        Hook for specifying fields.
  259
+        """
  260
+        return self.fields
  261
+
  262
+    def get_fieldsets(self, request, obj=None):
  263
+        """
  264
+        Hook for specifying fieldsets.
  265
+        """
  266
+        # We access the property and check if it triggers a warning.
  267
+        # If it does, then it's ours and we can safely ignore it, but if
  268
+        # it doesn't then it has been overriden so we must warn about the
  269
+        # deprecation.
  270
+        with warnings.catch_warnings(record=True) as w:
  271
+            warnings.simplefilter("always")
  272
+            declared_fieldsets = self.declared_fieldsets
  273
+        if len(w) != 1 or not issubclass(w[0].category, PendingDeprecationWarning):
  274
+            warnings.warn(
  275
+                "ModelAdmin.declared_fieldsets is deprecated and "
  276
+                "will be removed in Django 1.9.",
  277
+                PendingDeprecationWarning
  278
+            )
  279
+            if declared_fieldsets:
  280
+                return declared_fieldsets
  281
+
  282
+        if self.fieldsets:
  283
+            return self.fieldsets
  284
+        return [(None, {'fields': self.get_fields(request, obj)})]
248 285
 
249 286
     def get_ordering(self, request):
250 287
         """
@@ -478,13 +515,11 @@ def get_model_perms(self, request):
478 515
             'delete': self.has_delete_permission(request),
479 516
         }
480 517
 
481  
-    def get_fieldsets(self, request, obj=None):
482  
-        "Hook for specifying fieldsets for the add form."
483  
-        if self.declared_fieldsets:
484  
-            return self.declared_fieldsets
  518
+    def get_fields(self, request, obj=None):
  519
+        if self.fields:
  520
+            return self.fields
485 521
         form = self.get_form(request, obj, fields=None)
486  
-        fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
487  
-        return [(None, {'fields': fields})]
  522
+        return list(form.base_fields) + list(self.get_readonly_fields(request, obj))
488 523
 
489 524
     def get_form(self, request, obj=None, **kwargs):
490 525
         """
@@ -1657,12 +1692,11 @@ def is_valid(self):
1657 1692
 
1658 1693
         return inlineformset_factory(self.parent_model, self.model, **defaults)
1659 1694
 
1660  
-    def get_fieldsets(self, request, obj=None):
1661  
-        if self.declared_fieldsets:
1662  
-            return self.declared_fieldsets
  1695
+    def get_fields(self, request, obj=None):
  1696
+        if self.fields:
  1697
+            return self.fields
1663 1698
         form = self.get_formset(request, obj, fields=None).form
1664  
-        fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj))
1665  
-        return [(None, {'fields': fields})]
  1699
+        return list(form.base_fields) + list(self.get_readonly_fields(request, obj))
1666 1700
 
1667 1701
     def get_queryset(self, request):
1668 1702
         queryset = super(InlineModelAdmin, self).get_queryset(request)
2  docs/internals/deprecation.txt
@@ -426,6 +426,8 @@ these changes.
426 426
 * ``django.utils.datastructures.SortedDict`` will be removed. Use
427 427
   :class:`collections.OrderedDict` from the Python standard library instead.
428 428
 
  429
+* ``ModelAdmin.declared_fieldsets`` will be removed.
  430
+
429 431
 2.0
430 432
 ---
431 433
 
8  docs/ref/contrib/admin/index.txt
@@ -1218,6 +1218,14 @@ templates used by the :class:`ModelAdmin` views:
1218 1218
     changelist that will be linked to the change view, as described in the
1219 1219
     :attr:`ModelAdmin.list_display_links` section.
1220 1220
 
  1221
+.. method:: ModelAdmin.get_fields(self, request, obj=None)
  1222
+
  1223
+    .. versionadded:: 1.7
  1224
+
  1225
+    The ``get_fields`` method is given the ``HttpRequest`` and the ``obj``
  1226
+    being edited (or ``None`` on an add form) and is expected to return a list
  1227
+    of fields, as described above in the :attr:`ModelAdmin.fields` section.
  1228
+
1221 1229
 .. method:: ModelAdmin.get_fieldsets(self, request, obj=None)
1222 1230
 
1223 1231
     The ``get_fieldsets`` method is given the ``HttpRequest`` and the ``obj``
13  docs/releases/1.7.txt
@@ -113,6 +113,11 @@ Minor features
113 113
 * The admin's search fields can now be customized per-request thanks to the new
114 114
   :meth:`django.contrib.admin.ModelAdmin.get_search_fields` method.
115 115
 
  116
+* The :meth:`ModelAdmin.get_fields()
  117
+  <django.contrib.admin.ModelAdmin.get_fields>` method may be overridden to
  118
+  customize the value of :attr:`ModelAdmin.fields
  119
+  <django.contrib.admin.ModelAdmin.fields>`.
  120
+
116 121
 Backwards incompatible changes in 1.7
117 122
 =====================================
118 123
 
@@ -182,3 +187,11 @@ than simply ``myapp/models.py``, Django would look for :ref:`initial SQL data
182 187
 <initial-sql>` in ``myapp/models/sql/``. This bug has been fixed so that Django
183 188
 will search ``myapp/sql/`` as documented. The old location will continue to
184 189
 work until Django 1.9.
  190
+
  191
+``declared_fieldsets`` attribute on ``ModelAdmin.``
  192
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  193
+
  194
+``ModelAdmin.declared_fieldsets`` was deprecated. Despite being a private API,
  195
+it will go through a regular deprecation path. This attribute was mostly used
  196
+by methods that bypassed ``ModelAdmin.get_fieldsets()`` but this was considered
  197
+a bug and has been addressed.
10  tests/modeladmin/tests.py
@@ -51,6 +51,12 @@ def test_default_fields(self):
51 51
         self.assertEqual(list(ma.get_form(request).base_fields),
52 52
             ['name', 'bio', 'sign_date'])
53 53
 
  54
+        self.assertEqual(list(ma.get_fields(request)),
  55
+            ['name', 'bio', 'sign_date'])
  56
+
  57
+        self.assertEqual(list(ma.get_fields(request, self.band)),
  58
+            ['name', 'bio', 'sign_date'])
  59
+
54 60
     def test_default_fieldsets(self):
55 61
         # fieldsets_add and fieldsets_change should return a special data structure that
56 62
         # is used in the templates. They should generate the "right thing" whether we
@@ -97,6 +103,10 @@ class BandAdmin(ModelAdmin):
97 103
 
98 104
         ma = BandAdmin(Band, self.site)
99 105
 
  106
+        self.assertEqual(list(ma.get_fields(request)), ['name'])
  107
+
  108
+        self.assertEqual(list(ma.get_fields(request, self.band)), ['name'])
  109
+
100 110
         self.assertEqual(ma.get_fieldsets(request),
101 111
             [(None, {'fields': ['name']})])
102 112
 

0 notes on commit ebb3e50

Please sign in to comment.
Something went wrong with that request. Please try again.