Introduced ModelAdmin.get_fields() and refactored get_fieldsets() to use it.
Refs #18681. This also starts the deprecation of ModelAdmin.declared_fieldsets
This commit is contained in:
parent
61ecb5f48a
commit
ebb3e50243
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
---
|
||||
|
||||
|
|
|
@ -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``
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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']})])
|
||||
|
||||
|
|
Loading…
Reference in New Issue