#25488: BaseGenericInlineFormSet runs validation methods before linking form
instances to their related object
-------------------------------------+-------------------------------------
Reporter: arielpontes | Owner: nobody
Type: Bug | Status: new
Component: | Version: 1.8
contrib.contenttypes | Keywords:
Severity: Normal | BaseGenericInlineFormSet clean
| validation
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
I have a generic inline FormSet class generated like this:
{{{
ProductImageInlineFormset = generic_inlineformset_factory(
Image, form=ProductImageForm, extra=1)
}}}
and initialized like this:
{{{
product = get_object_or_404(Product.objects.by_id(id))
image_formset = ProductImageInlineFormset(
request.POST, request.FILES, instance=product)
}}}
When the individual forms that compose the FormSet are initialized, the
"product" object is not linked to their instances. This is only done in
the BaseGenericInlineFormSet.save_new method:
{{{
def save_new(self, form, commit=True):
setattr(form.instance, self.ct_field.get_attname(),
ContentType.objects.get_for_model(self.instance).pk)
setattr(form.instance, self.ct_fk_field.get_attname(),
self.instance.pk)
return form.save(commit=commit)
}}}
This causes problem when the Image class needs to do validation across
fields:
{{{
class Image(models.Model):
...
def clean(self):
related_class = self.content_type.model_class()
print(self.content_type.model_class())
}}}
The above code results in the following error when trying to save
ProductImageInlineFormsets:
{{{
django.db.models.fields.related.RelatedObjectDoesNotExist: Image has no
content_type.
}}}
The linking of Image to Product should be done in the form initialization
instead. At first sight, after a quick experiment, overriding the
`_construct_form` instead of the `save_new` seems to solve the problem:
{{{
def _construct_form(self, i, **kwargs):
form = super()._construct_form(i, **kwargs)
setattr(form.instance, self.ct_field.get_attname(),
ContentType.objects.get_for_model(self.instance).pk)
setattr(form.instance, self.ct_fk_field.get_attname(),
self.instance.pk)
return form
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/25488>
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/054.66e05d1ea2be417e41746d1a487e4fc6%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.