繁体   English   中英

显示来自 Model 表单的 Django 表单集的清洁方法的软警告

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM