Fixed #26607 -- Allowed customizing formset kwargs with ModelAdmin.get_formset_kwargs().

Thanks Nick Pope for reviews.
This commit is contained in:
manav014 2020-11-27 02:21:35 +05:30 committed by Mariusz Felisiak
parent 600ff26a85
commit 3119a6deca
5 changed files with 44 additions and 11 deletions

View File

@ -1946,6 +1946,20 @@ class ModelAdmin(BaseModelAdmin):
"admin/object_history.html"
], context)
def get_formset_kwargs(self, request, obj, inline, prefix):
formset_params = {
'instance': obj,
'prefix': prefix,
'queryset': inline.get_queryset(request),
}
if request.method == 'POST':
formset_params.update({
'data': request.POST.copy(),
'files': request.FILES,
'save_as_new': '_saveasnew' in request.POST
})
return formset_params
def _create_formsets(self, request, obj, change):
"Helper function to generate formsets for add/change_view."
formsets = []
@ -1959,17 +1973,7 @@ class ModelAdmin(BaseModelAdmin):
prefixes[prefix] = prefixes.get(prefix, 0) + 1
if prefixes[prefix] != 1 or not prefix:
prefix = "%s-%s" % (prefix, prefixes[prefix])
formset_params = {
'instance': obj,
'prefix': prefix,
'queryset': inline.get_queryset(request),
}
if request.method == 'POST':
formset_params.update({
'data': request.POST.copy(),
'files': request.FILES,
'save_as_new': '_saveasnew' in request.POST
})
formset_params = self.get_formset_kwargs(request, obj, inline, prefix)
formset = FormSet(**formset_params)
def user_deleted_form(request, obj, formset, index):

View File

@ -2088,6 +2088,22 @@ templates used by the :class:`ModelAdmin` views:
``obj_id`` is the serialized identifier used to retrieve the object to be
deleted.
.. method:: ModelAdmin.get_formset_kwargs(request, obj, inline, prefix)
.. versionadded:: 4.0
A hook for customizing the keyword arguments passed to the constructor of a
formset. For example, to pass ``request`` to formset forms::
class MyModelAdmin(admin.ModelAdmin):
def get_formset_kwargs(self, request, obj, inline, prefix):
return {
**super().get_formset_kwargs(request, obj, inline, prefix),
'form_kwargs': {'request': request},
}
You can also used it to set ``initial`` for formset forms.
.. method:: ModelAdmin.get_changeform_initial_data(request)
A hook for the initial data on admin change forms. By default, fields are

View File

@ -37,6 +37,9 @@ Minor features
* The ``admin/base.html`` template now has a new block ``header`` which
contains the admin site header.
* The new :meth:`.ModelAdmin.get_formset_kwargs` method allows customizing the
keyword arguments passed to the constructor of a formset.
:mod:`django.contrib.admindocs`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -951,6 +951,12 @@ class CityAdmin(admin.ModelAdmin):
inlines = [RestaurantInlineAdmin]
view_on_site = True
def get_formset_kwargs(self, request, obj, inline, prefix):
return {
**super().get_formset_kwargs(request, obj, inline, prefix),
'form_kwargs': {'initial': {'name': 'overridden_name'}},
}
class WorkerAdmin(admin.ModelAdmin):
def view_on_site(self, obj):

View File

@ -1117,6 +1117,10 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
self.assertContains(response, '<h1>View article</h1>')
self.assertContains(response, '<h2>Article 2</h2>')
def test_formset_kwargs_can_be_overridden(self):
response = self.client.get(reverse('admin:admin_views_city_add'))
self.assertContains(response, 'overridden_name')
@override_settings(TEMPLATES=[{
'BACKEND': 'django.template.backends.django.DjangoTemplates',