Django ModelForms从selectfield返回

时间:2013-10-07 19:50:54

标签: python django drop-down-menu django-forms

我在构建下拉列表(使用主动搜索过滤)时遇到问题,该下拉列表显示模型(课程)中存在的所有对象的属性(名称)。我发现select2是一个很好的opton来实现这个,因此安装了django-select2

这是我到目前为止的内容,为简洁起见省略了内容。

models.py

class Course(models.Model):
    courseID = models.CharField(max_length=6, blank="True", null="True")
    name = models.CharField(max_length=256, blank="True", null="True")
    hasProject = models.BooleanField(default=False)
    taughtBy = models.ManyToManyField(User)

urls.py

url(r'^courses/$', courses)

forms.py

from django import forms
import django_select2
from django_select2 import *
from models import Course

class CourseForm(forms.Form):  # also tried forms.ModelForm -> same results
    Title = ModelSelect2Field(widget=django_select2.Select2Widget(select2_options={
        'width': '400px',
        'placeholder': '',
    })
        , queryset=Course.objects.values_list('name', flat=True))

views.py

def courses(request):
    if request.method == 'POST':
        form = CourseForm()
        print "Form Type:", type(form)
        print "ERRORS:", form.errors
        if form.is_valid():
            course = form.cleaned_data['Title']
            print "Course Selected:", course
        return HttpResponseRedirect('/home/')
    else:
        form = CourseForm()
        return render(request, 'templates/home/courses.html', {'form': form})

courses.html

<form method="POST" id="courseForm" action="#" style="padding-bottom: 0px; margin-bottom: 0">
    <div class="badge pull-right">Hint: You can start typing the title of the course</div>
    {% csrf_token %}
        <table>
            {{ form }}
        </table>
        <div style="padding-left: 380px; padding-top: 10px">
            <button type="submit" class="btn btn-default">Submit</button>
        </div>
</form>

问题

表单始终无效且错误为空。表单类型为Type: <class 'coursereview.forms.CourseForm'>

我将下拉列表显示为ModelForm,但是平面列表包含对象的名称,因此我得到Type: <class 'coursereview.forms.CourseForm'>而不是ModelForm - 所以我可以解码选择的课程,并相应地显示相应的页面。

我见过this question并且正在考虑覆盖label_from_instance。当我使用django-select2时,我遇到了麻烦。我尝试将其设为ChoiceField,但表单仍然因错误而失效。此外,下拉列表看起来比select2更糟糕。 :P

class CourseForm(ModelForm):
    iquery = Course.objects.values_list('name', flat=True).distinct()
    iquery_choices = [('', 'None')] + [(id, id) for id in iquery]
    Title = forms.ChoiceField(iquery_choices,
                                required=False, widget=forms.Select())
    class Meta:
        model = Course
        exclude = ('taughtBy', 'courseID', 'name', 'hasProject')

理想情况下,我想使用前面提到的forms.py中使用的ModelSelect2Field,并从中返回选定的课程。

1 个答案:

答案 0 :(得分:0)

错误与您正在使用的选择字段无关。您只是不将POST数据传递给表单。

在视图的其余部分中也有一些缩进错误。整个事情应该是:

if request.method == 'POST':
    form = CourseForm(request.POST)
    if form.is_valid():
        course = form.cleaned_data['Title']
        print "Course Selected:", course
        return HttpResponseRedirect('/home/')
else:
    form = CourseForm()
return render(request, 'templates/home/courses.html', {'form': form})