gpt4 book ai didi

django - 提高形式。ValidationError 不工作

转载 作者:行者123 更新时间:2023-12-04 05:55:46 26 4
gpt4 key购买 nike

我有以下模型:

class Project(models.Model):
title = models.CharField(max_length="100")

pub_date = models.DateField(auto_now_add=True, editable=False)

budget = models.IntegerField()

class Milestone(models.Model):

title = models.CharField(max_length="50")

budget_percentage = models.IntegerField(max_length=2)

project = models.ForeignKey(Project)

在项目的创建表单中,我包含了里程碑的内联表单集。

我想验证提交项目时,至少创建了 4 个里程碑,并且所有里程碑的 budget_percentage 总和为 100

这是我的表格:

class BaseMilestoneProjectFormSet(BaseFormSet):
def clean(self):

if any(self.errors):
# Don't bother validating the forms unless each form is valid on its own
return

if len(self.forms) < REQUIRED_MILESTONES:
raise forms.ValidationError("At least %s milestones need to be created" % REQUIRED_MILESTONES)

# Set initial control variables
# Total percentage of budget to control
total_percentage = 0
# Date to control that milestones are linear, i.e. that second milestone isn't delivered before first
current_control_date = date.min

for i, form in zip(range(len(self.forms)), self.forms):

if i == 0 and form.budget_percentage > MAX_BUDGET_FIRST_MILESTONE:
raise forms.ValidationError("First milestone budget must not exceed %s percentage" % MAX_BUDGET_FIRST_MILESTONE)
elif form.budget_percentage > MAX_BUDGET_MILESTONE:
raise forms.ValidationError("Milestone's budget must not exceed %s percentage" % MAX_BUDGET_MILESTONE)

if form.estimated_delivery_date < current_control_date:
raise forms.ValidationError("Milestones must be linear, check your delivery dates")

# Set control variables for next iteration
current_control_date = form.estimated_delivery_date
total_percentage += form.budget_percentage

if total_percentage != 100:
raise forms.ValidationError("All milestones budget percentage should sum up to 100%")

当我提交包含 3 个空里程碑表单的表单时,它不会对第一个表单执行任何操作 forms.ValidationError(...)

我已经用 raise Exception() 验证了它实际上进入了 if,但它继续进行,就好像什么都没发生一样。

这是我的代码中的错误还是对 ValidationError 概念的误解?

任何帮助将不胜感激,提前致谢。

编辑:

我正在添加缺少的 View 代码

class DelayedModelFormMixin(ModelFormMixin):
def form_valid(self, form):
self.object = form.save(commit=False)
self.prepare_object_for_save(self.object)
self.object.save()
if hasattr(self.object, "save_m2m"):
self.object.save_m2m()
return super(ModelFormMixin, self).form_valid(form)

def prepare_object_for_save(self, obj):
pass

class ProjectNew(CreateView, DelayedModelFormMixin):
model = Project
success_url = '/projects/project/%(slug)s'
form_class = ProjectForm

@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
return super(ProjectNew, self).dispatch(request, *args, **kwargs)

def prepare_object_for_save(self, obj):
obj.owner = self.request.user
# Code for stacked milestones and rewards
context = self.get_context_data()
milestone_form = context['milestone_formset']
reward_form = context['reward_formset']
if milestone_form.is_valid() and reward_form.is_valid():
self.object = form.save()
milestone_form.instance = self.object
milestone_form.save()
reward_form.instance = self.object
reward_form.save()
return HttpResponseRedirect(success_url)

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

def get_context_data(self, **kwargs):
context = super(ProjectNew, self).get_context_data(**kwargs)
if self.request.POST:
context['milestone_formset'] = MilestoneFormSet(self.request.POST)
context['reward_formset'] = RewardFormSet(self.request.POST)
else:
context['milestone_formset'] = MilestoneFormSet()
context['reward_formset'] = RewardFormSet()
return context

最佳答案

如果我理解你的问题,问题是你正在计算表单集中有多少表单,但你想要/需要计算多少 BOUND表单在表单集中。

所以,我认为你需要更改这一行:

if len(self.forms) < REQUIRED_MILESTONES:

对于这些行:

bounded_forms = filter(lambda form:form.isbound(), self.forms)
if len(bounded_forms) < REQUIRED_MILESTONES:

然后您可以在执行时引发验证错误。

编辑:

也许您不了解表单集验证的工作原理。可能是this可以帮助,特别是这个短语:

The formset clean method is called after all the Form.clean methods have been called. The errors will be found using the non_form_errors() method on the formset.

如果我明白你说的意思

When I submit the form with 3 empty milestones forms it doesn't do nothing about the first forms.ValidationError(...)

那么,您将看不到引发的错误。因此,寻找它们的地方是表单集“non_form_errors”方法。在您的模板中放入类似这样的内容:

<span>{{milestone_formset.non_form_errors}}</span>

现在您应该看到您在里程碑表单集清理方法中引发的错误。

希望对您有所帮助!

关于django - 提高形式。ValidationError 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10867244/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com