Commit 2e7ca099 authored by Peter Sagerson's avatar Peter Sagerson Committed by Tim Graham
Browse files

[1.6.x] Fixes a race condition in the documentation.

The example for django.contrib.admin.ModelAdmin.get_form modifies
self.exclude. However, since ModelAdmin instances are global and have no
thread- or request-locality, this is not safe for concurrent
requests.[1] This updated documentation demonstrates a safe method to
override admin forms on a per-request basis.

[1] https://groups.google.com/forum/#!topic/django-users/AmoUDtEefyA

Backport of 0d1a9d20 from master
parent 7323e15d
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -1334,16 +1334,20 @@ templates used by the :class:`ModelAdmin` views:
    Returns a :class:`~django.forms.ModelForm` class for use in the admin add
    and change views, see :meth:`add_view` and :meth:`change_view`.

    If you wanted to hide a field from non-superusers, for example, you could
    override ``get_form`` as follows::
    The base implementation uses :func:`~django.forms.models.modelform_factory`
    to subclass :attr:`~form`, modified by attributes such as :attr:`~fields`
    and :attr:`~exclude`. So, for example, if you wanted to offer additional
    fields to superusers, you could swap in a different base form like so::

        class MyModelAdmin(admin.ModelAdmin):
            def get_form(self, request, obj=None, **kwargs):
                self.exclude = []
                if not request.user.is_superuser:
                    self.exclude.append('field_to_hide')
                if request.user.is_superuser:
                    kwargs['form'] = MySuperuserForm
                return super(MyModelAdmin, self).get_form(request, obj, **kwargs)

    You may also simply return a custom :class:`~django.forms.ModelForm` class
    directly.

.. method:: ModelAdmin.get_formsets(request, obj=None)

    Yields :class:`InlineModelAdmin`\s for use in admin add and change views.