问题描述
我有一个成功使用的模型表单和表单集,没有任何问题。
在表单集的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","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
解决方法
我相信通过执行以下操作,我已经能够适当地传递请求了:
Views.py:
def person(request,person_no):
person = get_user_model().objects.get(person_no=person_no)
formset = get_alignment_formset(person,request.POST,request)
Utils.py:
def get_alignment_formset(person,post_data=None,request=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,"request": request},queryset=Alignment.exclude_denied.filter(user=person).annotate(
num_end_date=Count("end_date")
).order_by(
"-end_date",),)
return formset
Forms.py:
class AlignmentForm(forms.ModelForm):
def __init__(self,*args,employee,request,**kwargs):
self.person = person
self.request = request
super().__init__(*args,**kwargs)
class AssignmentFormSet(forms.BaseModelFormSet):
def clean(self):
...
...
if alignment_error:
warning = "There was an issue"
messages.warning(form.request,warning)
它现在显示为预期的警告。