#24395: Cannot reference FK relation from inline ModelForm.save()
---------------------------------+-------------------------------------
     Reporter:  Starou           |                    Owner:  nobody
         Type:  Bug              |                   Status:  new
    Component:  Forms            |                  Version:  1.8alpha1
     Severity:  Release blocker  |               Resolution:
     Keywords:                   |             Triage Stage:  Accepted
    Has patch:  0                |      Needs documentation:  0
  Needs tests:  0                |  Patch needs improvement:  0
Easy pickings:  0                |                    UI/UX:  0
---------------------------------+-------------------------------------

Comment (by Starou):

 Jeez, Looks like I was Github logged-out  when I submitted a comment maybe
 a couple of hours ago. And same mistake now (and the textarea is
 reset...).
 Anyway, I was diging deeper in the Django admin code when I found out that
 the `Author` instance (`new_object` [1]) binded to the `BookFormset`
 instance was good where the one binded to the `BookFormset.forms` was not.

 
https://github.com/django/django/blob/master/django/contrib/admin/options.py#L1358

 {{{
     def changeform_view(self, request, object_id=None, form_url='',
 extra_context=None):
         ...
         ModelForm = self.get_form(request, obj)
         if request.method == 'POST':
             form = ModelForm(request.POST, request.FILES, instance=obj)
             if form.is_valid():
                 form_validated = True
                 new_object = self.save_form(request, form, change=not add)
 [1]
             else:
                 form_validated = False
                 new_object = form.instance
             formsets, inline_instances = self._create_formsets(request,
 new_object, change=not add)
             if all_valid(formsets) and form_validated:
                 self.save_model(request, new_object, form, not add)
                 self.save_related(request, form, formsets, not add)
                 if add:
                     self.log_addition(request, new_object)
                     return self.response_add(request, new_object)
                 else:
                     change_message =
 self.construct_change_message(request, form, formsets)
                     self.log_change(request, new_object, change_message)
                     return self.response_change(request, new_object)
 }}}

 The problem could be in `BaseInlineFormSet._construct_form()`:

 https://github.com/django/django/blob/master/django/forms/models.py#L884

 {{{
     def _construct_form(self, i, **kwargs):
         form = super(BaseInlineFormSet, self)._construct_form(i, **kwargs)
         if self.save_as_new:
             # Remove the primary key from the form's data, we are only
             # creating new instances
             form.data[form.add_prefix(self._pk_field.name)] = None

             # Remove the foreign key from the form's data
             form.data[form.add_prefix(self.fk.name)] = None

         # Set the fk value here so that the form can do its validation.
         fk_value = self.instance.pk
         if self.fk.rel.field_name != self.fk.rel.to._meta.pk.name:
             fk_value = getattr(self.instance, self.fk.rel.field_name)
             fk_value = getattr(fk_value, 'pk', fk_value)
         setattr(form.instance, self.fk.get_attname(), fk_value)
         return form
 }}}

 Using the following "patch" fixing the problem apparently:

 {{{
 -       setattr(form.instance, self.fk.get_attname(), fk_value)
 +       setattr(form.instance, self.fk.get_attname(), self.instance)
 }}}

 If you are not too much in a hurry, I can find some time tomorrow (GMT+1
 here) to write a proper patch with tests (cannot right now).

--
Ticket URL: <https://code.djangoproject.com/ticket/24395#comment:3>
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/064.efa40a9770789f91c4fd29b4c2e722d0%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to