需要在 Django Formset 中有一个必填字段和可选字段

Posted

技术标签:

【中文标题】需要在 Django Formset 中有一个必填字段和可选字段【英文标题】:Need to have a Required and Optional Fields in Django Formset 【发布时间】:2017-10-24 20:49:19 【问题描述】:

我创建了一个最多可以附加 5 个图像的表单集;

1 - 但我希望验证仅在用户未附加任何图像(ValidationError('atleast 1 image is required')) 时运行,

2- 该程序也不允许用户在附加 1、2 或 3 张图像时保存,这是我真正需要的。因此,如果有 1 张或 2 张图片,则应该允许保存。

3 - 我还需要默认选择 1 单选按钮,以使所选图像成为模板中显示的图像

模板

<form enctype="multipart/form-data" action="" method="post"> % csrf_token % 

% for hidden in form.hidden_fields %
     hidden 
% endfor %

 form.as_p 

 formset.management_form 
<div class="link-formset">

% for choice in formset %
<div>
  <label> choice.media </label>
  <input type="radio" name="featured">choice.featured_image.label 
</div>
% endfor %
</div>

<input type="submit" value=" submit_btn ">
</form>

forms.py

class ProductImagesForm(forms.ModelForm):
    media = forms.ImageField(label='Image', required=True)
    featured_image = forms.BooleanField(initial=True, required=True)
class Meta:
        model = ProductImages
        fields = ['media', 'featured_image']

ImagesFormset = modelformset_factory(ProductImages, fields=('media', 'featured_image'), extra=5)

views.py

def form_invalid(self, form, formset):
        return self.render_to_response(self.get_context_data(form=form, formset=formset))

    def form_valid(self, form, formset):
        return HttpResponseRedirect(self.get_success_url())

    def get(self, *args, **kwargs):
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        formset = ImagesFormset(queryset=ProductImages.objects.none())
        return self.render_to_response(self.get_context_data(form=form, formset=formset))

    def post(self, request, *args, **kwargs):
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        formset = ImagesFormset(self.request.POST, self.request.FILES or None)
        form_valid = form.is_valid()
        formset_valid = formset.is_valid()
        if (form.is_valid() and formset.is_valid()):
            seller = self.get_account()
            form.instance.seller = seller
            self.object = form.save()
            images_set = formset.save(commit=False)
            for img in images_set:
                img.product = self.object
                img.save()
            formset.save()
            return self.form_valid(form, formset)
        else:
            return self.form_invalid(form, formset)

【问题讨论】:

【参考方案1】:

您始终可以将min_nummax_num 传递给modelformset_factory

ImagesFormset = modelformset_factory(ProductImages, 
                                     fields=('media', 'featured_image'),  
                                     min_num=1,
                                     max_num=5,
                                     extra=5)

这将确保至少有 1 张图片,最多 5 张图片

【讨论】:

我已经这样做了,但是当没有附加图像时它仍然保存 您是否正在验证视图中的表单集? 是的,您可以在上面提供的 views.py 中查看我的验证 使用 validate_minvalidate_max (Refer here) 在最小和最大限制被违反时抛出错误。 ImagesFormset = modelformset_factory(ProductImages, fields=('media', 'featured_image'), min_num=1, max_num=5, validate_min=True, validate_max=True, extra=5) @dungu 你能上传你的完整视图吗?默认情况下,django 没有用于表单集的基于类的视图,示例显示了一个函数。甚至可能只是为了确保没有其他任何遗漏的模型

以上是关于需要在 Django Formset 中有一个必填字段和可选字段的主要内容,如果未能解决你的问题,请参考以下文章

TypeError: __init__() 在 Django Form & Formset 中有一个意外的关键字参数

访问django formset数据

如何在 Django 中根据需要为 formset_factory 设置每个字段(如何验证表单集中的空白表单)

Django - 基数为 10 的 int() 的 Formset 无效文字:''

没有实例的 Django Formset

django formset 未验证,因为需要 ID