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