【问题标题】:My form in Python Django is not submitting我在 Python Django 中的表单没有提交
【发布时间】:2017-06-22 12:13:49
【问题描述】:

我正在制作一个涉及使用 Django 制定时间表的表单,但由于某种原因,该表单没有提交。我使用 SQLite DB 浏览器进行了检查,似乎没有提交任何内容。

# choices.py

COURSE_NAME_CHOICES = (('a-plus', 'A+ PC Technician'), ('advance java', 'Advance Java/J2EE/Weblogic/Websphere'), ('a-s master', 'Agile-Scrum Master'), ('android mobile', 'Android Mobile Development'), ('autocad', 'AutoCAD'), ('bio-info', 'Bio-info Database Training course'), ('ba', 'Business Analyst (BA'), ('c-sharp', 'C# .Net'), ('ccna', 'CCNA Voice'), ('ceh', 'Certified Ethical Hacking'), ('checkpoint', 'Checkpoint Security Firewall Course'), ('ccie', 'Cisco CCIE IP Telephony'))
LOCATION_CHOICES = (('south_plainfield', 'South Plainfield'), ('hackensack', 'Hackensack'), ('fairfield', 'Fairfield'), ('eatontown', 'Eatentown'))
ROOM_CHOICES = (('A', 'South Plainfield A: CNA/MCSE'), ('B', 'South Plainfield B: SAS/.Net'), ('C', 'South Plainfield C: Cisco'), ('D', 'South Plainfield D: QA/.Net/Java'), ('E', 'South Plainfield E: Weblogic/Java/MCSE'), ('F', 'South Plainfield F: Unix/Linux'), ('G', 'South Plainfield G: Oracle/Clinic/Datawarehouse'))
START_TIME_CHOICES = (('eight-thirty am', '8:30 AM'), ('nine am', '9:00 AM'))
END_TIME_CHOICES = (('eight-thirty am', '8:30 AM'), ('nine am', '9:00 AM'))
INSTRUCTOR_CHOICES = (('adewale', 'Adewale Akinokun'), ('ajay', 'Ajay Kumar'))
TOTAL_HOURS_CHOICES = (('six', 6), ('ten', 10))
HOURS_PER_CLASS_CHOICES = (('two_and_half', 2.5), ('three', 3))
FREQUENCY_CHOICES = (('sunday', 'Sunday'), ('monday', 'Monday'), ('tuesday', 'Tuesday'), ('wednesday', 'Wednesday'), ('thursday', 'Thursday'), ('friday', 'Friday'), ('saturday', 'Saturday'))
STATUS_CHOICES = (('active', 'Active'), ('inactive', 'Inactive'), ('expired', 'Expired'), ('pending', 'Pending'))
INTERVAL_CHOICES = (('one_day', '1 Day'), ('two_days', '2 Days'))

# models.py

from django.db import models
from schedule.choices import *
import datetime

class Schedule(models.Model):
    course_name = models.CharField(max_length=128, choices=COURSE_NAME_CHOICES, default='a-plus')
    location = models.CharField(max_length=128, choices=LOCATION_CHOICES, default='south_plainfield')
    room = models.CharField(max_length=128, choices=ROOM_CHOICES, default='A')
    start_date = models.DateField(auto_now=False, auto_now_add=False, default=datetime.date.today)
    start_time = models.CharField(max_length=128, choices=START_TIME_CHOICES, default='eight-thirty am')
    end_time = models.CharField(max_length=128, choices=END_TIME_CHOICES, default='eight-thirty am')
    instructor = models.CharField(max_length=128, choices=INSTRUCTOR_CHOICES, default='adewale')
    total_hours = models.IntegerField(choices=TOTAL_HOURS_CHOICES, default='six')
    hours_per_class = models.FloatField(choices=HOURS_PER_CLASS_CHOICES, default='four_and_half')
    frequency = models.CharField(max_length=128, choices=FREQUENCY_CHOICES)
    status = models.CharField(max_length=128, choices=STATUS_CHOICES)
    interval = models.CharField(max_length=128, choices=INTERVAL_CHOICES, default='one_day')

def __str__(self):
    return self.course_name

# forms.py

from django import forms
from schedule.models import Schedule
from schedule.choices import *
import datetime

class ScheduleForm(forms.ModelForm):
    course_name = forms.ChoiceField(choices=COURSE_NAME_CHOICES, initial='a-plus', label="Course Name")
    location = forms.ChoiceField(choices=LOCATION_CHOICES, initial='south_plainfield', label="Location")
    room = forms.ChoiceField(choices=ROOM_CHOICES, initial='A', label="Room")
    start_date = forms.DateField(initial=datetime.date.today, widget=forms.DateInput(format='%m/%d/%Y'), input_formats=('%m/%d/%Y'), label="Start Date")
    start_time = forms.ChoiceField(choices=START_TIME_CHOICES, initial='eight-thirty am', label="Start Time")
    end_time = forms.ChoiceField(choices=END_TIME_CHOICES, initial='eight-thirty am', label="End Time")
    instructor = forms.ChoiceField(choices=INSTRUCTOR_CHOICES, initial='adewale', label="Instructor")
    total_hours = forms.ChoiceField(choices=TOTAL_HOURS_CHOICES, initial='six', label="Total Hours")
    hours_per_class = forms.ChoiceField(choices=HOURS_PER_CLASS_CHOICES, initial='four_and_half', label="Hours Per Class")
    frequency = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, choices=FREQUENCY_CHOICES, label="Frequency")
    status = forms.MultipleChoiceField(widget=forms.RadioSelect, choices=STATUS_CHOICES, label="Status")
    interval = forms.ChoiceField(choices=INTERVAL_CHOICES, initial='one_day', label="Interval")

    class Meta:
        model = Schedule
        fields = ('course_name', 'location', 'room', 'start_date', 'start_time', 'end_time', 'instructor', 'total_hours', 'hours_per_class', 'frequency', 'status', 'interval',)

        widgets = {}

# urls.py

from django.conf.urls import url
from schedule import views as  schedule_views

urlpatterns = [
    url(r'^start_one_schedule/$', schedule_views.start_One_Schedule, name='start_one_schedule'),
]

# views.py

def start_One_Schedule(request):
    form = ScheduleForm()
    if request.method == 'POST':
        form = ScheduleForm(request.POST)

        if form.is_valid():
            form.save(commit=True)
            return render(request, 'schedule/schedule.html', {})
        else:
            print(form.errors)

    return render(request, 'schedule/start_one_schedule.html', {'form': form})

# start_one_schedule.html

{% block main_content %}
<h2>Initial Course Schedule</h2>
<br>
<form id="schedule_form" method="post" action="/schedule/start_one_schedule/">
    {% csrf_token %}
    {% for field in form %}
        <table class="init_sched_form">
            <tr class="init_sched_row">
                <td class="init_sched_label">{{ field.label_tag }}</td>
                <td class="init_sched_field">{{ field }}</td>
            </tr>
        </table>
    {% endfor %}
    <button type="submit" name="submit">Initial Schedule</button>
</form>
{% endblock %}

表单确实可以显示在 html 本身上。只是提交按钮根本不起作用。我确保仔细检查了所有内容,并且我 90% 确定我所做的一切都是正确的。有人有想法吗?我真的很感激。谢谢。

编辑:我想我找到了问题所在。通过在模板中显示表单错误,我能够看到一些条目的几个字段是无效的。我通过将choices.py中的选项用整数和浮点数转换为字符串来修复其中两个,这不是一个优雅的修复,但它适用于这种情况。

其次,开始日期字段无效,因为显然它只接受格式为 YYYY-MM-DD 的日期,而不是像我想要的那样 MM/DD/YYYY,所以我将初始日期改回,但如果有人有解决方案请告诉我。

最后,最后两个错误让我感到难过。他们在这里:

状态 - 输入值列表。

频率 - 选择一个有效的选项。 ['tuesday', 'wednesday'] 不是可用的选项之一。

这两个都是多选字段,频率是多选复选框,状态是单选。我不知道这些错误是什么意思,因为只有设置选项可供选择,所以我不知道如何“输入值列表”或为什么这些不是有效的选择。

【问题讨论】:

  • “提交按钮根本不起作用”是什么意思?网址不会变吗?
  • 是的。 URL 保持不变。页面可能会在瞬间闪烁,但仍停留在同一页面上。
  • 您的 print(form.errors) 没有返回任何内容。因此错误会打印在控制台上,然后再次呈现相同的内容。但是您没有在模板中显示错误。在字段循环上方添加 {{form.errors}}。
  • 由于新发现,我编辑了问题。

标签: python django forms


【解决方案1】:

一般

您正在覆盖和复制开箱即用的东西。模型表单生成的字段出奇地好。抛开关于字符字段的一些信息,您可以将表单简化为以下内容:

class ScheduleForm(forms.ModelForm):
    class Meta:
        model = Schedule
        fields = ('course_name', 'location', 'room', 'start_date', 'start_time', 'end_time', 'instructor', 'total_hours', 'hours_per_class', 'frequency', 'status', 'interval',)
        widgets = { 'frequency': forms.CheckboxSelectMultiple, 'status': forms.RadioSelect }

CharField 不是容器

您不能使用CharField 进行多项选择。它只包含一个字符串类型的项目。因此,传递给它的任何值都被强制转换为字符串表示 ['foo', 'bar'] 以获得列表。这与选择不匹配,因此验证失败。这通常通过与频率模型的 ManyToManyRelation 来解决。是的,数据是“静态的”,但是在这里使用数据库表真的有那么大的不同吗?

越来越受欢迎的解决方案是使用django.contrib.postgres 中的ArrayFieldJSONField。虽然它有效,但它使关系变得更加困难,因此最好在仅显示而不过滤此信息的情况下使用。

RadioSelect 返回一项

这基本上是相反的。现在您正在尝试使用一个小部件,它为需要多个值的表单字段返回一个值。

【讨论】:

  • 感谢您的建议,我想我已经解决了。但是,如果我用你写的替换了 Schedule Form,我不需要确认其中一些字段是 ChoiceFields 吗?另外,我解决了最后两个问题,即使它们仍然是 CharFields。
  • 模型表单由模型定义生成。如果模型上的字段定义了选项,Django 将为模型表单选择一个 ChoiceField(默认选择为小部件)。当它是外键时,它也会选择一个ChoiceField,但会使用相关的管理器生成选择。
猜你喜欢
  • 2021-08-07
  • 1970-01-01
  • 2011-03-13
  • 1970-01-01
  • 1970-01-01
  • 2021-09-20
  • 1970-01-01
  • 1970-01-01
  • 2016-02-26
相关资源
最近更新 更多