我正在使用inlineformset构建一个带子类别的表单。我使用inlineform,因为我希望子类别在类别下嵌套。我想验证每个子类别表单的字段(权重),以加起来达到100%。我使用clean()但无法使其工作,并且错误消息不会显示在模板上。我已经对过去的帖子进行了一些挖掘,但没有看到任何解决方案。我也调查了djangoproject,但无处可去。请帮忙!我在这里想念的是什么?!! 在我的forms.py中,我有:
from django import forms
from django.forms.models import inlineformset_factory
from .models import Category, SubCategory
from django.forms import BaseInlineFormSet
class SubInline(BaseInlineFormSet):
def clean(self):
allocation = 0
for form in self.forms:
if not hasattr(form, 'cleaned_data'):
continue
weight = form.cleaned_data
allocation += int(weight.get('weight'))
if allocation != 100:
raise forms.ValidationError("Weights must sum to 100")
SubCategoryFormSet = inlineformset_factory(Category,
SubCategory,
fields = ['title',
'description',
'weight'],
formset = SubInline,
extra = 0,
can_delete =True)
在我看来,我有:
class CategorySubCategoryUpdateView(TemplateResponseMixin, View):
template_name = 'manage/subcategory/formset.html'
category = None
def get_formset(self, data = None):
return SubCategoryFormSet(instance = self.category, data=data)
def dispatch(self, request, pk):
self.category = get_object_or_404(Category,
id=pk,
owner=request.user)
return super(CategorySubCategoryUpdateView,
self).dispatch(request)
def get(self, request, *args, **kwargs):
formset = self.get_formset()
return self.render_to_response({'category': self.category,
'formset':formset})
def post(self, request, *args, **kwargs):
formset = self.get_formset(data=request.POST)
if formset.is_valid():
formset.save()
return redirect('categoryportfolios:manage_category_list')
else:
print("100 is needed")
return self.render_to_response({'category':self.category,
'formset': formset})
在我的模板中:
<form class="form-horizontal" action = "" method = "post">
{{formset.management_form}}
{% for form in formset %}
{% for fields in form %}
<div class = "form-group">
{{ fields.errors}}
{{ fields.label_tag }}</br>{{ fields }}
{% csrf_token%}
</div>
{% endfor %}
{% endfor %}
<input type = "submit" class="button" value="save subcategories">
</form>
</div>
</div>
</div>
</div>