【问题标题】:How to render error or validation messages to ModelForm in 2022如何在 2022 年向 ModelForm 呈现错误或验证消息
【发布时间】:2022-01-06 02:55:41
【问题描述】:

我已经花了几个小时在互联网上研究,尤其是官方 Django 文档,但我仍然不清楚 2022 年哪个是最佳选择(因为我在 SO 上读到的几乎所有问题都是 > 6 年) 并且对于酥脆的形式是否更好有不同的意见。

仍然推荐脆皮形式吗?

我如何(以及最推荐的方式)获得典型的验证错误消息?

喜欢:“this field is mandatory”还是“this input accepts numbers only”?我已经看到一些使用这些默认消息的 Django 页面,但我不知道如何在我的 ModelForm 字段中显示它们。

假设我有以下模型:

class Project(models.Model):
    project_name = models.CharField(max_length=250, null=False, blank=False)
    status = models.CharField(
        max_length=250, 
        null=True, 
        blank=True, 
        default=PROJECT_STATUS_DEFAULT,
        choices=PROJECT_STATUS,
    )
    creation_date = models.DateField(max_length=250, null=False, blank=False)
    project_code = models.IntegerField(null=True, blank=True)
    notes = models.CharField(max_length=250, null=True, blank=True)

对于Project 模型,我有以下ModelForm

class CreateNewProjectForm(ModelForm):
    creation_date = forms.DateField(widget=forms.DateInput(format = '%d/%m/%Y'), input_formats=settings.DATE_INPUT_FORMATS) #UK Date format
    class Meta:
        model = Project
        fields = '__all__'

视图,当我尝试创建一个新对象Project

def add_new_project(request):
    context = {}
    if request.method == 'POST':
        form = CreateNewProjectForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('project_page')
        else:
            print (form.errors)
            form = CreateNewProjectForm()
        context['form'] = form
    return render(request, 'new_project.html', context)

HTML 部分:

<div class="card h-100">
    <div class="card-header project-page-header">
        <h3>Create A New Project</h3>
    </div>
    <div class="card-body px-0 new-project-card-body">
        <div class="cardItem">
            <div class="row">
                <div class="col">
                    <div class="row">
                        <div class="tab-pane fade show active" id="general">
                            <form id="newProjectForm" method="POST" action="new_project">
                                {% csrf_token %}
                                <div class="accordion accordion-flush" id="accordionGeneral">
                                    <div class="accordion-item">
                                        <h2 class="accordion-header" id="general-headingOne">
                                            <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#general-collapseOne" aria-expanded="false" aria-controls="general-collapseOne">
                                            Details
                                            </button>
                                        </h2>
                                        <div id="general-collapseOne" class="accordion-collapse collapse show" aria-labelledby="general-headingOne" data-bs-parent="#accordionGeneral">
                                            <div class="accordion-body">
                                                <div class="row">
                                                    <div class="col-5">
                                                        <ul class="list-unstyled">
                                                            <li class="mt-3">
                                                                <div class="row">
                                                                    <div class="col-sm ph-tabs-field-label">
                                                                        Project Name
                                                                    </div>
                                                                    <div class="col-sm">
                                                                        <input type="text" name="project_name" class="form-control" aria-label="Project Name">
                                                                    </div>
                                                                </div>
                                                            </li>
                                                            <li class="mt-3">
                                                                <div class="row">
                                                                    <div class="col-sm ph-tabs-field-label">
                                                                        Status
                                                                    </div>
                                                                    <div class="col-sm">
                                                                        <select name="status" class="selectpicker show-tick w-100"  aria-label="Status">
                                                                        {% for status in project_status %}
                                                                            {% if forloop.first %} 
                                                                            <option value="{{ status.id }}" selected>{{ status.text }}</option> 
                                                                            {% else %}
                                                                            <option value="{{ status.id }}">{{ status.text }}</option>
                                                                            {% endif %}
                                                                        {% endfor %}
                                                                        </select>
                                                                    </div>
                                                                </div>
                                                            </li>
                                                            <li class="mt-3">
                                                                <div class="row">
                                                                    <div class="col-sm ph-tabs-field-label">
                                                                        Creation Date
                                                                    </div>
                                                                    <div class="col-sm">
                                                                        <input type="text" name="creation_date" class="form-control">
                                                                    </div>
                                                                </div>
                                                            </li>
                                                            <li class="mt-3">
                                                                <div class="row">
                                                                    <div class="col-sm ph-tabs-field-label">
                                                                        Project Code
                                                                    </div>
                                                                    <div class="col-sm">
                                                                        <input type="text" name="project_code" class="form-control">
                                                                    </div>
                                                                </div>
                                                            </li>
                                                        </ul>
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="accordion-item">
                                        <h2 class="accordion-header" id="general-headingThree">
                                            <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#general-collapseThree" aria-expanded="false" aria-controls="general-collapseThree">
                                            Note
                                            </button>
                                        </h2>
                                        <div id="general-collapseThree" class="accordion-collapse collapse" aria-labelledby="general-headingThree" data-bs-parent="#accordionGeneral">
                                            <div class="accordion-body"><textarea name="notes" class="form-control" rows="7"></textarea></div>
                                        </div>
                                    </div>
                                    <button type="submit" id="projectEditBtn" form="newProjectForm" class="btn btn-info rounded-0">Save</button>
                                </div>
                            </form>
                        </div>
                    </div>        
                </div>
            </div>
        </div>
    </div>
</div>

我看到了像 this 这样的解决方案,但问题是我的表单字段分布在不同的手风琴上,我不能使用像 {% if form.errors %} 这样的东西,我需要为每个字段提供更具体的东西。

【问题讨论】:

    标签: django django-forms


    【解决方案1】:

    首先像这样更新你的视图

    
    def add_new_project(request):
        context = {}
        if request.method == 'POST':
            form = CreateNewProjectForm(request.POST)
            if form.is_valid():
                form.save()
                return redirect('project_page')
            else:
                print (form.errors)
                context['form'] = form
                return render(request, 'new_project.html', context)
        context['form'] = CreateNewProjectForm()
        return render(request, 'new_project.html', context)
    

    您可以像这样为每个字段指定错误

    {% if form.field_name.errors %}
      {{ form.field_name.errors }}
    {% endif %}
    

    【讨论】:

    • 我尝试了您的代码,但没有成功。 print(form.errors) 在控制台中返回:&lt;ul class="errorlist"&gt;&lt;li&gt;project_name&lt;ul class="errorlist"&gt;&lt;li&gt;This field is required.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt; 但带有:{% if form.project_name.errors %} {{ form.project_name.errors }} {% endif %} 没有打印任何内容。
    • 你好@Cheknov,因为你没有在上下文中正确传递你的无效表单
    • 你好@Cheknov 检查我已经编辑了我的答案
    猜你喜欢
    • 1970-01-01
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-15
    • 1970-01-01
    • 2010-12-30
    相关资源
    最近更新 更多