我在Python Django中的表单没有提交

时间:2017-06-22 12:13:49

标签: python django forms

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

# 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格式,所以我改变了初始状态,但是如果有人有解决方案的话请告诉我。

最后,最后两个错误是让我感到困惑的错误。他们在这里:

status - 输入值列表。

频率 - 选择有效选项。 ['周二','周三']不是可用的选择之一。

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

1 个答案:

答案 0 :(得分:1)

一般

你正在重写和复制开箱即用的东西。模型表单生成的字段非常好。抛开关于charfields的一点,您可以将表单缩小为以下内容:

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进行多项选择。它只包含一个string类型的项目。因此传递给它的任何值都被强制转换为字符串表示['foo', 'bar']以获取列表。这与选择不匹配,因此验证失败。这通常通过对Frequency模型的ManyToManyRelation来解决。是的,数据是“静态的”,但在这里使用数据库表确实有很大的不同。

越来越受欢迎的解决方案是使用ArrayField中的JSONFielddjango.contrib.postgres。虽然它有效,但它会使关系变得更加困难,所以如果只显示这些信息而不进行过滤,最好使用它。

RadioSelect返回一个项目

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