Django表单仅在表单有效时保存相关对象

时间:2019-10-22 11:09:10

标签: python django django-forms

我认为我在这里有一个不太常见的功能,至少我找不到答案。

我要实现的是在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()之前被调用,我还没找到解决该问题的方法。如果表单无效,我想阻止创建新的通讯员实例。

让我知道我是否可以改进此问题和提示。

1 个答案:

答案 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)

宾果! :)