Opened 8 years ago
Last modified 6 years ago
#27560 closed Bug
Formset.save() crashes for model with foreign key to concrete base model — at Version 2
Reported by: | Lorenzo Peña | Owned by: | nobody |
---|---|---|---|
Component: | Forms | Version: | 1.9 |
Severity: | Normal | Keywords: | formset inline_formset inline_formsetfactory |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
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.
Change History (2)
comment:1 by , 8 years ago
Summary: | Formset.save for model with foreign key to concrete base model → Formset.save() crashes for model with foreign key to concrete base model |
---|---|
Type: | Uncategorized → Bug |
comment:2 by , 8 years ago
Description: | modified (diff) |
---|
Could you include more complete details about how to reproduce the issue? My try to reproduce gives
save() prohibited to prevent data loss due to unsaved related object 'some_model'.
atformset.save()
.