#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 django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
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.

Reply via email to