用于动态隐藏输入字段的Django表单

时间:2018-01-11 16:59:01

标签: django forms validation

我有两个模型,帖子和附件。附件有Post的外键。

我有一个PostFreateView和PostForm。

在撰写帖子时,您可以使用jquery-fileupload(AJAX)上传图像。如果上传文件,则会在<textarea>Hello World! Click "enter" for more lines...</textarea>附加以下行。

<form>

值(1,2和3)是附件模型的PK,以便在保存帖子时在帖子和附件之间建立关系。

我能够在PostCreateView中获得一个列表:

<input type="hidden" name="attachments" value="1" />
<input type="hidden" name="attachments" value="2" />
<input type="hidden" name="attachments" value="3" />

但是,我想在PostForm中声明表单字段以进行以下验证:

  • PK必须是整数。
  • 附件的外键必须与这些PK一起为空。
  • 必须限制PK的数量(5或10)。

帖子可能没有附件,因此附件隐藏输入标签最初不存在。这就是为什么要有一个表格领域很难。这些都附加了AJAX / jQuery。如果它很困难,我想知道在CreateView中覆盖哪种方法的最佳实践。

谢谢。

1 个答案:

答案 0 :(得分:0)

我自己回答。

  1. PostForm没有Attachment的PK隐藏字段。

  2. PostAttachmentForm继承PostFormclean_attachment()检查列表项是否全部为整数。

    class PostAttachmentForm(PostForm):
        attachments = forms.IntegerField(widget=forms.HiddenInput(), required=False)
    
        def clean_attachments(self):
            data = self.data.getlist('attachments')
    
            if not data and not all(isinstance(item, int) for item in data):
                raise forms.ValidationError("PK must be integers.")
    
            return data
    
  3. PostCreateViewget_form_class而不是form_class字段。

    def get_form_class(self):
        if self.request.method == 'POST':
            # NOTE: Hidden fields must be validated.
            return PostAttachmentForm
        else:
            # NOTE: Hidden fields are not prepopulated but appended to form by AJAX.
            return PostForm
    
  4. form_valid()用于帖子和附件之间的相关性和验证

    def form_valid(self, form):
        response = super().form_valid(form)
    
        # TODO: limit number
    
        # Attachments are not related to any post yet.
        attachments = Attachment.objects.filter(
            pk__in=form.cleaned_data['attachments'],
            post__isnull=True,
        )
        self.object.attachments.set(attachments)
    
        return response
    
  5. 如果你有更好的方法,我真的很感激。