【问题标题】:Django bound form is invalid but not ValidationError raisedDjango 绑定表单无效但未引发 ValidationError
【发布时间】:2019-03-01 14:41:49
【问题描述】:

我的 Django 表单有问题。当我单击表单中的提交按钮时,没有数据保存到数据库中。我发现数据是绑定,但它没有通过form.is_valid() 函数。下面分别是forms.py、views.py、urls.py和new-event.html的代码:
forms.py

from django import forms
class EventForm(forms.Form):
    name = forms.CharField(label='event-name',
                           max_length=50,
                           widget=forms.TextInput(attrs={'class': 'form-control', 'id': 'event-name', 'name': 'event-name'}))

    start_datetime = forms.DateTimeField(
    widget=forms.DateTimeInput(attrs={'class': 'form-control', 'id': 'start-datetime', 'name': 'start-datetime', 'type': 'datetime-local'}))

    end_datetime = forms.DateTimeField(
    widget=forms.DateTimeInput(attrs={'class': 'form-control', 'id': 'end-datetime', 'name': 'end-datetime', 'type': 'datetime-local'}))

    event_category = forms.ChoiceField(widget=forms.Select(attrs={'class': 'custom-select', 'id': 'event-type'}),
    choices=((None, 'Please select an option'), ('Daily Life', 'Daily Life'), ('Study', 'Study'), ('Social', 'Social'), ('Work', 'Work')))

    description = forms.CharField(max_length=250, widget=forms.Textarea(attrs={'class': 'form-control', 'id': 'description', 'name': 'description'}), required=False)

views.py

from django.shortcuts import render, redirect
from .models import Entry
from .forms import EventForm
from django.views.decorators.http import require_POST

# request is required that represents HttpResponse
# return value can be response, JSON or template

def index(request):
    entries = Entry.objects.order_by('-date_added')
    context = {'entries': entries}
    return render(request, 'event/list-events.html', context)

def new_event(request):
    form = EventForm()
    context = {'form': form}
    return render(request, 'event/new-event.html', context)

@require_POST
def add_event(request):

    if request.method == 'POST':

        form = EventForm(request.POST)

        if form.is_bound: print('form is bound')
        else: print('form is unbound')

        if form.is_valid():
            print('form is valid')
            new_entry = Entry(name=form.cleaned_data['name'], start_datetime=form.cleaned_data['start_datetime'],
                              end_datetime=form.cleaned_data['end_datetime'], category=form.cleaned_data['event_category'],
                              description=form.cleaned_data['description'])
            new_entry.save()

        else:
            print('form is invalid')
            return render(request, 'event/new-event.html', {'form': form})

        return redirect('index')

    # else:
    #     form = EventForm()

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('new-event/', views.new_event, name='new_event'),
    path('add-event/', views.add_event, name='add_event')
]

new-event.html

{% extends 'todo/base.html' %}

{% block title %}New Entry{% endblock %}

{% block content %}
    <form action="{% url 'add_event' %}" method="POST" class="container-fluid">
        {% csrf_token %}
        <div class="form-group row">
            <label for="event-name" class="col-sm-2 col-form-label">Event</label>
            <div class="col-sm-10">
                {{ form.name }}
            </div>
        </div>
        <div class="form-group row">
            <label for="event-type" class="col-sm-2 col-form-label">Event type</label>
            <div class="col-sm-10">
                {{ form.event_category }}
            </div>
        </div>
        <div class="form-group row">
            <label for="start-datetime" class="col-sm-2 col-form-label">Start Time</label>
            <div class="col-sm-10">
                {{ form.start_datetime }}
            </div>
        </div>
        <div class="form-group row">
            <label for="end-datetime" class="col-sm-2 col-form-label">End Time</label>
            <div class="col-sm-10">
                {{ form.end_datetime }}
            </div>
        </div>

        <div class="form-group">
            {{ form.description }}
        </div>
        <input type="submit" name="submit" value="Submit" class="btn btn-primary">
    </form>
{% endblock %}

我的终端上的输出是:form is bound form is invalid... 我确信我不会陷入 bound 和 instance 之间的概念混淆。谁能给我一些关于这是如何发生的提示?

【问题讨论】:

  • 终于找到了无法成功将数据保存到数据库的原因。原因是start_datetime和end_datetime被指定为input type=datetime_local,与默认类型input type=text相反,当前版本的Django并不完全支持。见Django form.DateTimeInput。谢谢@Daniel Roseman 的帮助 :)

标签: python django forms validation


【解决方案1】:

我不确定您为什么认为这是一个问题。您的表单已正确绑定到 POST 数据;然后,该数据被验证,发现没有通过验证。

要查看原因 - 并允许用户更正问题 - 您应该在模板上输出 {{ form.errors }},或为每个字段使用单独的错误属性,例如 {{ form.name.errors }} 等。

【讨论】:

  • 如果我问了一个愚蠢的问题,请原谅我,因为我是 Django 新手。您的意思是 POST 数据已经过验证,因此它在 form.is_valid() 条件下失败?
  • 是的。我不确定是什么让你感到困惑。
  • 好的。我目前遇到的问题是我无法从form.cleaned_data 字典中获取start_datetime 和end_datetime 字段,因为它们在清理后不包含在内。这是我从Django's documentation 中读到的内容:“如果您的数据未通过验证,则cleaned_data 字典仅包含有效字段:”我还检查了原始数据是否包含两个日期值并且确实包含。那么如何从cleaned_data 访问两个日期值?
  • 好吧,它们不存在是因为字段无效,form.errors 会告诉你原因。
  • 打印form.errors 显示:&lt;ul class="errorlist"&gt;&lt;li&gt;start_datetime&lt;ul class="errorlist"&gt;&lt;li&gt;Enter a valid date/time.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;end_datetime&lt;ul class="errorlist"&gt;&lt;li&gt;Enter a valid date/time.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;。有人遇到同样的情况,post 的答案是在DateTimeField 中指定input_formats 在forms.py 中。我跟着,但仍然出现相同的错误消息。
猜你喜欢
  • 2010-11-10
  • 2013-09-28
  • 1970-01-01
  • 2013-02-02
  • 1970-01-01
  • 2010-09-25
  • 2020-10-14
  • 2011-12-19
  • 2020-05-15
相关资源
最近更新 更多