#27231: Initialize forms in ModelAdmin like View (i.e. add get_form_kwargs to
contrib.admin)
----------------------------------+--------------------------------------
Reporter: thauk-copperleaf | Owner: nobody
Type: Uncategorized | Status: new
Component: contrib.admin | Version: 1.10
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------
Comment (by thauk-copperleaf):
In django.contrib.admin.ModelAdmin, the form class is obtained by get_form
(1) and then instaniated in one of three different ways, depending on if
the request was a POST (2) or not (3 and 4).
{{{
@csrf_protect_m
@transaction.atomic
def changeform_view(self, request, object_id=None, form_url='',
extra_context=None):
#
# ...
#
add = object_id is None
#
# ...
#
ModelForm = self.get_form(request, obj) # (1)
if request.method == 'POST':
form = ModelForm(request.POST, request.FILES, instance=obj) #
(2)
#
# ...
#
else:
if add:
initial = self.get_changeform_initial_data(request)
form = ModelForm(initial=initial) # (3)
formsets, inline_instances =
self._create_formsets(request, form.instance, change=False)
else:
form = ModelForm(instance=obj) # (4)
formsets, inline_instances =
self._create_formsets(request, obj, change=True)
}}}
In django.views.generic.edit.FormMixin, get_form returns an instantiated
form; it gets the form class via get_form_class() (1), and instantiates it
with the returned value from get_form_kwargs() (2). get_form_kwargs() sets
the "initial" value based on the returned value from get_initial() (3),
and sets "data" and "files" based on if the request was a POST (4)
{{{
def get_form(self, form_class=None):
"""
Returns an instance of the form to be used in this view.
"""
if form_class is None:
form_class = self.get_form_class() # (1)
return form_class(**self.get_form_kwargs()) # (2)
def get_form_kwargs(self):
"""
Returns the keyword arguments for instantiating the form.
"""
kwargs = {
'initial': self.get_initial(), # (3)
'prefix': self.get_prefix(),
}
if self.request.method in ('POST', 'PUT'): # (4)
kwargs.update({
'data': self.request.POST,
'files': self.request.FILES,
})
return kwargs
}}}
One discrepancy is that ModelForm.get_form() returns a form class, while
FormMixin.get_form() returns a form instance with
FormMixin.get_form_class() returns a form class.
API alignment might look something like this:
{{{
def get_form_class(self, request, obj=None, **kwargs):
#
# ... Old contents of get_form()
#
def get_form(self, request, obj=None, form_class=None, **kwargs):
if form_class is None:
form_class = self.get_form_class(request, obj=obj)
return form_class(**self.get_form_kwargs(request, obj=obj))
def get_form_kwargs(self, request, obj=None, obj=None):
if request.method == 'POST':
kwargs = {
'data': request.POST,
'files': request.FILES,
'instance': obj,
}
else if obj:
kwargs = {
'initial': self.get_changeform_initial_data(request),
}
else:
kwargs = {
'instance': obj,
}
return kwargs
@csrf_protect_m
@transaction.atomic
def changeform_view(self, request, object_id=None, form_url='',
extra_context=None):
#
# ...
#
form = self.get_form(request, obj)
if request.method == 'POST':
#
# ...
#
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/27231#comment:6>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/074.d59ab5da6e43a02d63b9180291f12c69%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.