#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.

Reply via email to