#27560: Formset.save() crashes for model with foreign key to concrete base model
-------------------------------------+-------------------------------------
Reporter: Lorenzo Peña | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.9
Severity: Normal | Resolution:
Keywords: formset | Triage Stage:
inline_formset | Unreviewed
inline_formsetfactory |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by Lorenzo Peña:
Old description:
> {{{
> class A(models.Model):
> pass
>
> class B(A):
> pass
>
> class C(models.Model):
> some_model = models.ForeignKey(SomeModel)
> a_link = models.ForeignKey(A)
> }}}
>
> I'm using an inlineformset_factory where the parent model is SomeModel
> and the child model is C.
> When calling formset.save() I'm getting an error from
> django/forms/models.py (line 910)
>
> {{{
> 910: pk_value = getattr(self.instance, self.fk.remote_field.field_name)
> 911: setattr(obj, self.fk.get_attname(), getattr(pk_value, 'pk',
> pk_value))
> }}}
>
> The getattr call fails
>
> if I wrap both lines in: if hasattr(self.instance,
> self.fk.remote_field.field_name):
> it works good.
>
> Not sure if the condition is the way to fix the bug or it's just
> preventing the original cause from happening.
New description:
Model hierharchy
{{{
class ConcreteBase(models.Model):
...
class Descendant(ConcreteBase):
...
}}}
Master / Detail type models (e.g. Order and OrderDetail)
{{{
class MasterModel(models.Model):
...
class DetailModel(models.Model):
master = models.ForeignKey(MasterModel, ...)
concrete_base = models.ForeignKey(ConcreteBase, ...)
}}}
Form definition
{{{
class MasterModelForm(forms.ModelForm):
...
class DetailModelForm(forms.ModelForm):
...
# master excluded from fields as will be manually added in view
...
}}}
Formset definition
{{{
DetailModelFormset = inlineformset_factory(MasterModel, DetailModel,
form=DetailModelForm)
}}}
View definition
{{{
from django.views.generic.edit import CreateView #### <---- the error only
happens on create view of MasterModel
class MasterModelAdd(CreateView):
model = MasterModel
form_class = MasterModelForm
...
def form_valid(self, form):
master_instance = form.save()
detail_formset = DetailModelFormset()(self.request.POST)
detail_instances = detail_formset.save(commit=False) ### <------
this line raises the error
for detail_instance in detail_instances: ### <----- it never gets
here
detail_instance.master = master_instance
detail_instance.save()
}}}
When calling formset.save() I'm getting an error from
django/forms/models.py (line 910) regardless of the value of commit
passed.
{{{
910: pk_value = getattr(self.instance, self.fk.remote_field.field_name)
911: setattr(obj, self.fk.get_attname(), getattr(pk_value, 'pk',
pk_value))
}}}
The getattr call fails
if I wrap both lines in: {{{ if hasattr(self.instance,
self.fk.remote_field.field_name): }}}
it works good.
Not sure if the condition is the way to fix the bug or it's just
preventing the original cause from happening.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/27560#comment:2>
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/066.5e9da8251a6beeb4381a7ae0673fdec3%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.