Django表单验证有问题

时间:2014-03-25 17:18:27

标签: django django-forms

我一直在努力解决这个问题,一直在查找关于如何进行表单验证的Django文档,但似乎无法取得任何进展,所以我转向SO寻求帮助。

我有一个带有Django表单的网站,我在其上显示两个ChoiceFields。一个包含汽车品牌列表,另一个包含汽车模型列表。第二个字段最初为空白,并在用户选择汽车品牌时填充我的Javascript。当用户同时选择品牌和型号并单击“提交”时,页面将加载有关用户选择的品牌/型号的信息。

现在,如果用户只选择一个品牌而没有品牌,或者根本没有品牌,我想要显示一个错误,说明"请选择品牌和型号继续。"

到目前为止,无论我尝试过什么,我都无法获得该功能。

forms.py

from django import form

makes = (('Honda', 'Honda'), ('Ford', 'Ford'), ('Nissan', 'Nissan'), ('GM', 'GM'))

class SearchForm:
    make = forms.ChoiceField(choices=makes, required=True, widget=forms.Select(attrs={'size':'5', 'autofocus'='on'}))
    model = forms.ChoiceField(required=True, widget=forms.Select(attrs={'size':'5'}))

    def clean(self):
        cleaned_data = super(SearchForm, self).clean()
        m1 = cleaned_data.get("make")
        m2 = cleaned_data.get("model")

        if not m1 or not m2:
            raise forms.ValidationError("Please select a make and model to continue.")
        return cleaned_data

    def clean_model(self):
        data = self.cleaned_data["model"]

        if not data: // if the user didn't select a model
             raise forms.ValidationError("Please select a model to continue.")
        return data

views.py

from mysite.forms import SearchForm

def search(request):
    searchform = SearchForm()
    return render(request, "search.html", {"form" : searchform})

def car_info(request):
    searchform = SearchForm(request.GET)
    if searchform.is_valid():
        // code to parse the make and model and return the corresponding page
        return render(request, "car_info.html", {})
    else: // there is an error so redisplay the page with the new form object
        return render(request, "search.html", {"form" : searchform})

search.html

...
<form action="{% url 'mysite.views.car_info' %}" method="GET" name="sform">
    {{ searchform.make }}
    {{ searchform.model }}
    <button>Search away!</button>
</form>

{% if searchform.errors %}
    <div class="error">{{ searchform.non_field_errors.as_text }}</div>
{% endif %}
...

在我的index.html中,我有一个指向搜索页面的链接:{% url 'mysite.views.search' %}

我得到的行为是,当我不选择制作时,我会收到错误。这是对的。当我选择一个制作但不选择模型时,我也会收到错误。好。但是,当我选择一个品牌和型号时,我得到了同样的错误,它不会带我到car_info.html页面。

非常感谢任何帮助。

修改

发生了一些奇怪的事情。我更改了forms.py以提出验证错误,只是为了看看会弹出什么。

raise forms.ValidationError(str(clean_make) + " " + str(clean_model)) 

然后,我选择两个制作和模型,并且引发错误输出正确的制作,但是&#34;无&#34;对于模型,即使我选择了一个模型!这是为什么?

编辑2

好的,我可能知道为什么模型正在输出&#34;无&#34;。在我的forms.py中,我没有指定模型的选项,因为这将填充在search.html页面上运行的此Javascript代码:

$(document).ready(function() {
    $("#id_make").change(init);
});

function init() {
    populateModel();
}

function populateModel() {
    var make = $("#id_make")
    var model = $("#id_model") //select fields created by Django ChoiceField widget

    var mod_values = values[mak.val()];
    model.empty();
    $.each(mod_values, function(k,v) {
        model.append($("<option></option>").attr("value", v).text(k));
    });
}

var values = {
    "Honda" : { 
        "Accord" : "accord",
        "Civic" : "civic",
        "Odyssey" : "odyssey",
    },

    "Ford" : {
         "F-150" : "f150", 
         "Taurus" : "taurus", 
         "Fusion" : "fusion",
    },

    "Nissan" : { 
          "Sentra" : "sentra",
          "Maxima" : "maxima", 
          "Altima" : "altima",
    }, 
}

所以,当我这样做时:

 model = cleaned_data.get("version")

那是空的,对吧?

现在,我现在不确定如何修复它。

1 个答案:

答案 0 :(得分:1)

作为第一个调试步骤,由于您使用的是GET方法,因此您应该能够检查URL的正确性。当您同时选择品牌和型号提交表单时,URL应如下所示:

?make=XXXX&model=YYYY

既然如此,那么表单正在清理模型是完全正确的,因为它基本上认为模型没有有效的条目。您需要创建一个验证模型的自定义字段:

class ModelField(forms.ChoiceField):

    def valid_value(self, value):
        if value is not None and value != '':
            return True
        return False

然后,以您的形式:

model = ModelField(required=True, widget=forms.Select(attrs={'size':'5'}))