【发布时间】:2020-12-02 08:13:13
【问题描述】:
我有一个模型表单和一个表单集,我正在成功使用,没有问题。
在我的表单集的clean 方法中,我执行了一些逻辑 - 但以前导致ValidationError 的要求之一现在正在更改,应该只是在模板中对用户的一个简单警告。
我的模型表单和表单集如下所示:
class AlignmentForm(forms.ModelForm):
def __init__(self, *args, employee, **kwargs):
self.person = person
super().__init__(*args, **kwargs)
class Meta:
model = Alignment
fields = [
"alignment",
"start_date",
"end_date",
]
class AlignmentFormSet(forms.BaseModelFormSet):
def clean(self):
if any(self.errors):
return
# I've trimmed out additional logic and checks
# This is the area of concern
alignment_error = {}
for i, form in enumerate(self.forms):
if not end_date:
if alignment == "Wrong":
alignment_error = {
"alignment": alignment,
"added_message": "Corrected",
}
if alignment_error:
raise forms.ValidationError(
f"""
The alignment is
({alignment_error['alignment']}) and must
be ({alignment_error['added_message']}).
"""
)
return form
当前的ValidationError 需要成为仅在模板中呈现给用户的一条消息 - 但不会阻止表单验证和保存。
我尝试过这样做:
if alignment_error:
messages.warning(
request,
f"""
The alignment is
({alignment_error['alignment']}) and must
be ({alignment_error['added_message']}).
""",
)
但这不起作用,因为我无权访问请求。我可以访问它吗?
实现这一目标的最佳方法是什么?我仍然想显示该消息,但只是不希望它阻止表单保存。
编辑添加:
views 函数如下所示:(基本部分)
def person(request, person_no):
person = get_user_model().objects.get(person_no=person_no)
formset = get_alignment_formset(person, request.POST)
if request.method == "POST":
# If add alignment is in form the util method will handle adding
# the extra form if add alignment not in post data actually validate
# and process the form
if "add_alignment" not in request.POST:
if formset.is_valid():
# If form is valid we want to get the person being updated
# current alignment
alignment_before = Alignment.get_active_primary(person)
for formset_form in formset:
if formset_form.has_changed():
alignment = formset_form.save(commit=False)
alignment.user = person
if not alignment.pk:
alignment.created_by = request.user
alignment.modified_by = request.user
alignment.save()
else:
alignment = formset_form.save(commit=False)
# do some logic with position control here
warnings, errors = update_foil_alignment_app(
request.user, person, alignment_before, alignment
)
if errors or warnings:
for error in errors:
messages.error(request, error)
for warning in warnings:
messages.warning(request, warning)
kwargs = {"person_no": person.person_no}
return redirect("app_name:person", **kwargs)
messages.success(
request,
f"""
You have successfully updated alignments for
{alignment.user.last_name}, {alignment.user.first_name}.
""",
)
kwargs = {"person_no": person.person_no}
return redirect("app_name:person", **kwargs)
utils 函数如下所示:
def get_alignment_formset(person, post_data=None):
extra = 0
# If add alignment in post_data we add the extra form and clear out
# post data, we don't actually want to post only data
if post_data:
if "add_alignment" in post_data:
post_data = None
extra = 1
formset = modelformset_factory(
Alignment,
fields=("alignment", "start_date", "end_date"),
extra=extra,
form=AlignmentForm,
formset=AlignmentFormSet,
)
formset = formset(
post_data or None,
form_kwargs={"person": person},
queryset=Alignment.exclude_denied.filter(user=person).annotate(
num_end_date=Count("end_date")
).order_by(
"-end_date",
),
)
return formset
【问题讨论】:
-
你能发表你正在使用的观点吗?
-
@SukhpreetSingh 我已经添加了视图和随之而来的 utils 调用
标签: python django forms django-forms modelform