【问题标题】:Validate django inline formset验证 django 内联表单集
【发布时间】:2016-03-15 15:11:05
【问题描述】:

我使用了 django 内联表单集,所以在两个模型上制作一个单一的 crud。 与 django 表单不同,django formset 一次可以处理多个表单。所以验证 django formset 对我来说真的很困惑。但是我需要验证我的 django formset。我真的没有找到任何还没有解决办法。

我有两个模型,即 折扣折扣产品。我使用 django formset 的 折扣产品表单集折扣表

默认情况下,表单集允许用户在创建新实例或更新新实例时避免使用所有表单,这实际上是有道理的,因为可以有 15 或 20 个表单。在我的系统中,我也遵循相同的方式。

在我的折扣表单集中,有两个字段,即primary variantvariants

如果用户没有填写表单集的任何表单的任何字段,他可以这样做并且只能创建或更新折扣表单对象,这很好。(记住折扣表单位于折扣产品表单集之上)。

但如果他只填写variant 字段并将primary variant 字段清空,那么用户不应该允许这样做,因为在我的系统中,如果没有primary variant,就无法创建或更新variant。但在这一点上我无法验证它。因为它是一个表单集。我真的需要知道如何进行这种类型的验证。

这是他创建视图,我将折扣折扣产品组合在一起。(仅提供创建视图,我希望解决方案能够更新视图也一样)

class DiscountCreate(RequestPassingFormViewMixin, WammuCreateView):
    model = Discount
    template_name = 'dashboard/discount_form.html'
    form_class = DiscountForm

    def get_form_kwargs(self, *args, **kwargs):
        kwargs = super(DiscountCreate, self).get_form_kwargs(*args, **kwargs)
        common = get_object_or_404(Common, pk=self.kwargs['common_pk'])
        discount = Discount(common=common)
        kwargs['instance'] = discount
        return kwargs

    def get(self, request, *args, **kwargs):
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        DiscountProductInlineFormSet = inlineformset_factory(Discount, DiscountProducts,
                                                        form=DiscountProductForm,
                                                        can_delete=True, extra=5)
        DiscountProductInlineFormSet.form = staticmethod(curry(DiscountProductForm, request=request))
        discount_product_formset = DiscountProductInlineFormSet(instance=self.object)
        return self.render_to_response(
        self.get_context_data(form=form, discount_formset=discount_product_formset))

   def post(self, request, *args, **kwargs):
        self.object = Discount()
        form = self.get_form(self.form_class)
        DiscountProductInlineFormSet = inlineformset_factory(Discount, DiscountProducts,
                                                        form=DiscountProductForm,
                                                        can_delete=True, extra=5)
        DiscountProductInlineFormSet.form = staticmethod(curry(DiscountProductForm, request=request))
        if form.is_valid():
            self.object = form.save(commit=False)
        else:
            discount_product_formset = DiscountProductInlineFormSet(request.POST,
                                                              instance=self.object)
            return self.render_to_response(
            context=self.get_context_data(form=form, discount_formset=discount_product_formset))

        promotion_product_formset = DiscountProductInlineFormSet(request.POST, instance=self.object)
        if discount_product_formset.is_valid():
            self.object.save()
            discount_product_formset.save()
            return super(Discountreate, self).form_valid(form)
        else:
            return self.render_to_response(
                context=self.get_context_data(form=form, discount_formset=discount_product_formset))

这是我的表单,折扣折扣产品都驻留,

class DiscountForm(RequestPassingFormMixin, ModelForm):
    class Meta:
        model = Discount

    def __init__(self, *args, **kwargs):
        super(PromotionForm, self).__init__(*args, **kwargs)
        common = Chain.objects.get(pk=self.request.session.get('chain_pk'))

    class DiscountProductForm(autocomplete_light.ModelForm):    
        class Meta:
            model = DiscountProducts
            fields = ['code', 'variants', 'primary_variant']

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("request")
        super(DiscountProductForm, self).__init__(*args, **kwargs)
        common = Chain.objects.get(pk=self.request.session.get('common_pk'))
        self.fields['variants'].queryset = Variant.objects.filter(product__common__pk=common.pk)
        self.fields['primary_variant'].queryset = Variant.objects.filter(product__common__pk=common.pk) 

【问题讨论】:

    标签: python django forms validation


    【解决方案1】:

    如果至少有一个字段不为空,则验证表单集中的字段,因此默认情况下一切都应该按照您的预期工作。 你也可以阅读cleaning and validating fields that depend on each other

    【讨论】:

    • 我必须跟踪一个空字段,clean 方法是否跟踪空字段? @Alex Poleha
    • 你所说的“跟踪”是什么意思?如果您将两个字段都留空,则不会引发验证错误。如果您在任何表单集上填写一个字段,但将任何其他必填字段留空,则会引发验证错误。这不是你需要的吗? @Rego
    【解决方案2】:

    只需将参数min_num=1validate_min=True添加到inlineformset_factory

    【讨论】:

      【解决方案3】:

      这是我遇到您的问题时的解决方案,在您的意见中.py

      from django.forms.formsets import formset_factory, BaseFormSet
      
      # Enables field required on formset even without filling up a singlefield
      class RequiredFormSet(BaseFormSet):
           def __init__(self, *args, **kwargs):
               super(RequiredFormSet, self).__init__(*args, **kwargs)
              for form in self.forms:
                  form.empty_permitted = False
      
      def view(request):
          formset = formset_factory(CollegeForm, extra=5, formset=RequiredFormSet)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-17
        • 2013-09-03
        • 2023-04-09
        • 2011-06-02
        • 2010-10-27
        • 2013-11-15
        • 2014-08-17
        相关资源
        最近更新 更多