亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

有沒有辦法為 Django 中的每個 ValidationError 設置不同的 id?

有沒有辦法為 Django 中的每個 ValidationError 設置不同的 id?

MMMHUHU 2022-07-26 16:46:22
這是我的表單的外觀:class TestForm(forms.ModelForm):    class Meta:        model = Restaurant        fields = [            'title',            'content',        ]    def clean(self, *args, **kwargs):        title = self.cleaned_data.get("title")        content = self.cleaned_data.get("content")        error_dict = {}        if len(title) < 3:            error_dict['title'] = ValidationError("testerror1")        if len(content) < 3:            error_dict['content'] = ValidationError('testerror2')        if error_dict:            raise ValidationError(error_dict)如果我嘗試用空提交表單title 并content顯示兩條錯誤消息(testerror1、testerror2),它們會出現在每個字段標簽上方,如下所示:<ul class="errorlist">    <li>test2</li></ul>但是如果客戶端單擊輸入,我想隱藏它們中的每一個,所以我嘗試使用 Jquery:$("#my_form_id").find('input, textarea').click(function() {    $(this).closest('ul').hide();})沒有成功(它沒有找到任何<ul>元素。我的問題是,有沒有辦法為每個錯誤設置不同的 id?這樣我就可以分別管理每一個。
查看完整描述

1 回答

?
料青山看我應如是

TA貢獻1772條經驗 獲得超8個贊

您可以在每條錯誤消息上放置一個唯一標識符,但這有點繁瑣,我不確定我會認為它有多“安全”。我認為對于您想要的更好的選擇是迭代表單中的字段,并一次呈現字段和錯誤消息。這篇文章的結尾描述了如何做到這一點。如果您真正想要的是將標識符放在錯誤消息上,而無需遍歷模板中的字段……好吧,請繼續閱讀。


艱難的道路

為了獲得為每個錯誤消息呈現的不僅僅是一個簡單的文本消息(不破壞模板中的表單),您需要ErrorList為ModelForm. 該類ErrorList在 HTML 中執行錯誤的呈現,因此通過創建和使用子類,您可以更改呈現的內容 - 包括從 ValidationError 本身添加特殊代碼。


from django.forms.utils import ErrorList

from django.utils.html import format_html, format_html_join


# This overrides the ErrorList class to provide the additional rendering

#  features you want - in this example it only overrides it for the `ul` output

class ErrorListDerivative(ErrorList):

    def as_ul(self):

        if not self.data:

            return ''


        # Key part 1: the UL is now being rendered with a class for

        #  each of the errors which includes the error code from the

        #  ValidationError. You can then locate the UL by looking for that class.

        return format_html(

            '<ul class="{{}} {}">{{}}</ul>'.format(' '.join(('errorcode{}'.format(e.code) for e in self.data))),

            self.error_class,

            # Key Part 2: This adds the code from the validation error to the individual LIs

            format_html_join('', '<li class="errorforcode{}">{}</li>', ((e.code, e.message) for e in self.data))  

        )

現在已經創建了一個以您想要的方式呈現事物的 ErrorList,TestForm 需要使用它。


class TestForm(forms.ModelForm):


    # This __init__ is what makes the ModelForm use the custom ErrorList class you've created. 

    #  The BaseForm from which ModelForm is derived (a few layers of inheritence deep) has an `error_class` argument to receive the class used to render errors. This just injects your custom class.

    def __init__(self, *args, **kwargs):

        kwargs_new = {'error_class': ErrorListDerivative}

        kwargs_new.update(kwargs)

        super().__init__(*args, **kwargs_new)


    class Meta:

        model = Restaurant

        fields = [

            'title',

            'content',

        ]


然后,在您的 TestForm clean 函數中,將附加值傳遞code給ValidationErrors


    def clean(self, *args, **kwargs):

        title = self.cleaned_data.get("title")

        content = self.cleaned_data.get("content")

        error_dict = {}


        # Key Part 3: Here we're including the custom error code in the 

        #  ValidationError, which will be rendered out

        if len(title) < 3:

            error_dict['title'] = ValidationError("testerror1", code='title')

        if len(content) < 3:

            error_dict['content'] = ValidationError('testerror2', code='content')


        if error_dict:

            # Must admit, not sure if adding a code here will do anything at all

            raise ValidationError(error_dict, code='3')

完成此操作后,HTML 輸出應如下所示:


<form id="my_form_id" method="post" novalidate="">

    <label for="id_title">Title:</label>

    <ul class="errorlist errorcodetitle">

        <li class="errorforcodetitle">testerror1</li>

    </ul><input type="text" name="title" value="ao" maxlength="100" required="" id="id_title">

    <label for="id_content">Content:</label>

    <ul class="errorlist errorcodecontent">

        <li class="errorforcodecontent">testerror2</li>

    </ul><input type="text" name="content" value="ao" maxlength="100" required="" id="id_content">

    <button type="submit">Submit</button>

</form>

現在有了這些 UL 上的類,您可以使用該字段的名稱來定位相關的 UL 并將其隱藏。


$("#my_form_id").find('input, textarea').click(function(evt) {

    $('.errorcode' + this.name).hide();

})

慣用的方式

如果您不想進入那個兔子洞,另一種方法是做一些更像 django 文檔中的示例“循環遍歷表單的字段”(https://docs.djangoproject.com/en/3.0/ topic/forms/#looping-over-the-form-s-fields)它不會在錯誤消息中為您提供自定義類(或 ids,無論您最終添加什么),但它更慣用。


類似于以下內容...


{% for field in form %}

    <div class="fieldWrapper">

        <div class="errorcode{{field.html_name}}">

            {{ field.errors }}

        </div>

        {{ field.label_tag }} {{ field }}

        {% if field.help_text %}

        <p class="help">{{ field.help_text|safe }}</p>

        {% endif %}

    </div>

{% endfor %}

然后您可以使用與上述相同的 jquery:


$("#my_form_id").find('input, textarea').click(function(evt) {

    $('.errorcode' + this.name).hide();

})


查看完整回答
反對 回復 2022-07-26
  • 1 回答
  • 0 關注
  • 81 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號