![](/img/trans.png)
[英]Django: Calling custom Model method from Form clean method. “Unbound Method”?
[英]Show soft warning from clean method of Django Formset for Model Form
我有一个 model 表单和一个我成功使用的表单集,没有问题。
在我的表单集的clean
方法中,我执行了一些逻辑 - 但是以前导致ValidationError
的要求之一现在正在更改,应该只是在模板中向用户发出一个简单的警告。
我的 model 表单和表单集如下所示:
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']}).
""",
)
但这不起作用,因为我无权访问请求。 我可以访问它吗?
实现这一目标的最佳方法是什么? 我仍然想显示该消息,但只是不希望它阻止表单保存。
编辑添加:
视图 function 看起来像这样:(基本部分)
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)
实用程序 function 如下所示:
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
我相信此时我已经能够通过执行以下操作适当地传递请求:
视图.py:
def person(request, person_no):
person = get_user_model().objects.get(person_no=person_no)
formset = get_alignment_formset(person, request.POST, request)
实用程序.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)
它现在按预期显示为警告。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.