我使用了django内联formset,所以在两个模型上做一个单一的crud。 与django表单不同, django formset 一次使用多个表单。所以我真的很困惑我验证django formset。但我需要验证我的django formset。我真的没有找到了任何解决方案。
我有两种模式,即折扣和折扣产品。我已经使用折扣产品套餐的django formset与折扣表单
默认情况下,formsets允许用户在创建新实例或更新新实例时避免所有表单,这实际上是有意义的,因为可以有15或20个表单。在我的系统中,我也遵循相同的方式。
在我的折扣表单中,有两个字段primary variant
和variants
。
如果用户没有填写任何形式的表单集的任何字段,他可以这样做,只能创建或更新折扣表单对象,这很好。(记得折扣表格位于折扣产品表格集之上。
但如果他只填写variant
字段并显示primary variant
字段,则用户不应允许这样做,因为在我的系统中,无法创建variant
或更新时没有primary variant
。但是在这一点上我无法验证它。因为它是一个formsets。我真的需要知道如何进行这种类型的验证。
这里是创建视图,我将折扣和折扣产品结合起来。(仅提供创建视图,我希望解决方案能够对于更新视图也是相同的)
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))
这是我折扣和 Disount Products 所在的表单,
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)
答案 0 :(得分:0)
当我遇到你的问题时,这是我的解决方案,在你的views.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)
答案 1 :(得分:0)
如果至少有一个字段不为空,则验证formset中的字段,因此默认情况下一切都应该按预期工作。 您还可以阅读cleaning and validating fields that depend on each other。
答案 2 :(得分:0)
只需将参数min_num=1
和validate_min=True
添加到inlineformset_factory