我认为我在这里有一个不太常见的功能,至少我找不到答案。
我要实现的是在text input with autocomplete
上的related model
及其标签字段。然后,给定的文本应该get_or_create
相关的模型。这已经可以工作,但是问题是,无论表单是否为is_valid,新的相关模型实例都保存在表单提交中。
考虑到以下情况和实施情况(为便于总览而缩短)
class Correspondent(models.Model):
label = models.CharField(_("label"), max_length=100, unique=True)
class Document(BaseModel):
correspondent = models.ForeignKey(
Correspondent,
verbose_name=_("correspondent"),
on_delete=models.PROTECT,
related_name="documents",
)
具有以下格式:
class DocumentForm(forms.ModelForm):
correspondent = forms.CharField(
label=_("correspondent"), widget=forms.TextInput(attrs={"class": "awesomplete"})
)
class Meta:
model = Document
exclude = ["created_by", "modified_by"]
def clean_correspondent(self, *args, **kwargs):
# ToDo: don't save the FKed instance if complete form isn't valid
user = self.initial["user"]
data = self.cleaned_data["correspondent"]
obj = Correspondent.objects.get_or_create(label=data)
return obj
所以这里的问题是obj.save()
,它在form.is_valid()
之前被调用,我还没找到解决该问题的方法。如果表单无效,我想阻止创建新的通讯员实例。
让我知道我是否可以改进此问题和提示。
答案 0 :(得分:0)
感谢Dipen Dadhaniya向正确的方向推动我。
我需要从ModelForm中排除 actual 字段,因此我可以按照CharField的需要以更简单的方式进行清理。之后,在整个表单确实有效之后,我便可以在视图中执行逻辑了。
表单丢失完整的自定义clean_correspondent方法。
class DocumentForm(forms.ModelForm):
correspondent_label = forms.CharField(
label=_("correspondent"), widget=forms.TextInput(attrs={"class": "awesomplete"})
)
class Meta:
model = Document
exclude = ["correspondent", "created_by", "modified_by"]
该逻辑现在位于DocumentCreateView
方法的form_valid()
中。
def form_valid(self, form):
form.instance.modified_by = self.request.user
form.instance.correspondent, created = Correspondent.objects.get_or_create(
label=form.cleaned_data["correspondent_label"]
)
return super().form_valid(form)
宾果! :)