数据输入人员不断添加和复制模型,因为他们无法轻松搜索现有的内联项目,因此我在 Brand ModelForm 中添加了字段以允许自动建议 Brand 模型。
问题
Brand.name 是 Brand 模型的必填字段。因此,当仅填写 Autocomplete 字段时(在将现有品牌重新分配给当前公司的情况下), form.save() 失败(它为空,但 save() 需要 Brand.name ,无论如何我都不需要不想将表单保存为模型实例,因为我刚刚重新分配了)。
如果在重新分配字段中提交了品牌,我只想将该 Brands.company 设置为父表单集值,然后静默返回而不尝试保存 ModelForm。
该关系是从品牌模型到公司模型的外键——一个公司可能有很多品牌。
一张图说一千个字,所以...
代码
class BrandAdminForm(forms.ModelForm):
reassign_existing = AutoCompleteSelectField('brand', required=False,)
confirm_reassign = BooleanField(required=False, help_text=_("Are you sure you want to reassign the brand?"))
def __init__(self, *args, **kwargs):
super(BrandAdminForm, self).__init__(*args, **kwargs)
self.fields['name'].required = False
def clean(self):
cleaned_data = super(BrandAdminForm, self).clean()
import ipdb; ipdb.set_trace()
if cleaned_data['reassign_existing'] \
and cleaned_data['confirm_reassign'] \
and not self.instance.pk:
self.instance = cleaned_data['reassign_existing']
cleaned_data['reassign_existing'].company = self.instance.company
cleaned_data['id'] = self.instance.id
cleaned_data['category'] = self.instance.category.all()
cleaned_data['website'] = self.instance.website
cleaned_data['twitter_handle'] = self.instance.twitter_handle
cleaned_data['wikipedia_uri'] = self.instance.wikipedia_uri
cleaned_data['email'] = self.instance.email
cleaned_data['name'] = self.instance.name
return cleaned_data
elif cleaned_data['reassign_existing'] \
and cleaned_data['confirm_reassign'] \
and self.instance.pk:
raise forms.ValidationError("You can't reassign AND add/edit a brand in the same form. Clear one of the sections.")
else:
if not cleaned_data['name']:
msg = u"You must add a name to a new brand."
self._errors["name"] = self.error_class([msg])
return cleaned_data
class Meta:
model = Brand
这种方法几乎有效,只有在重新分配品牌的类别时才会列出。这是M2M领域。
编辑 1
当'reassign_existing'中有值时,我试图覆盖保存以不保存但最终得到一个
'NoneType' object has no attribute 'company_id'
这是设置
class BrandAdminForm(forms.ModelForm):
reassign_existing = AutoCompleteSelectField('brand', required=False,
)
confirm_reassign = BooleanField(required=False, help_text=_("Are you sure you want to reassign the brand?"))
def __init__(self, *args, **kwargs):
super(BrandAdminForm, self).__init__(*args, **kwargs)
self.fields['name'].required = False
def clean(self):
cleaned_data = super(BrandAdminForm, self).clean()
if cleaned_data['reassign_existing'] \
and cleaned_data['confirm_reassign'] \
and not self.instance.pk:
cleaned_data['reassign_existing'].company = self.instance.company
cleaned_data['reassign_existing'].save()
return cleaned_data
elif cleaned_data['reassign_existing'] \
and cleaned_data['confirm_reassign'] \
and self.instance.pk:
raise forms.ValidationError("You can't reassign AND add/edit a brand in the same form. Clear one of the sections.")
else:
if not cleaned_data['name']:
msg = u"You must add a name to a new brand."
self._errors["name"] = self.error_class([msg])
return cleaned_data
def save(self, *args, **kwargs):
if not self.cleaned_data['reassign_existing']:
super(BrandAdminForm, self).save(*args, **kwargs)
class Meta:
model = Brand