Django表示不调用自定义验证器

时间:2018-04-12 09:55:43

标签: django django-forms

我正在使用Django 2.0。这是我的forms.py

class PostcodeForm(forms.Form):
    postcode = forms.CharField(required=True, widget=forms.TextInput(
        attrs={
            'placeholder': "enter a postcode",
        }
    ))

    def clean_postcode(self):
        postcode = self.clean_data.get('postcode', '')
        print('clean_postcode', postcode)
        if postcode != 'something':
            raise forms.ValidationError(_("Please enter a valid postcode"), code='invalid')
        return data

我的views.py

def index(request):
    form = PostcodeForm()
    context = {
        'form': form
    }
    return render(request, 'index.html', context)

我的index.html

<form class="form-inline" id="lookup_postcode" action="{% url 'lookup_postcode' %}" method="get">
    {% csrf_token %}
    {{ form.non_field_errors }}
    {{ form.postcode.errors }}
    {{ form.postcode }}
    <button type="submit">Submit</button>
</form>

但是当我输入除“&#39;”之外的任何其他值时,表单仍会提交。我也没有在控制台中看到任何打印声明,因此看起来好像验证器没有被运行。

我做错了什么?

3 个答案:

答案 0 :(得分:6)

目前,您总是在form = PostcodeForm()进行GET和POST请求。这意味着表单不受任何数据的约束,因此它永远不会有效或有任何错误。

在Django中,处理表单的典型视图如下所示:

from django.shortcuts import redirect

def index(request):
    if request.method == 'POST':
        form = PostcodeForm(request.POST)
        if form.is_valid():
            # form is valid. Process form and redirect
            ...
            return redirect('/success-url/')
    else:
        form = PostcodeForm()
    context = {
        'form': form
    }
    return render(request, 'index.html', context)

为此,您需要将表单方法更改为“发布”。

<form class="form-inline" id="lookup_postcode" action="{% url 'lookup_postcode' %}" method="post">

如果您将表单方法保留为“get”,则需要将表单绑定到request.GET。您可能想要添加一个检查,否则在首次访问索引视图时会出现必填字段的错误。

if 'postcode' in request.GET:
    # bound form
    form = PostcodeForm(request.GET)
else:
    # unbound, empty form
    form = PostcodeForm()

答案 1 :(得分:0)

使用下面的表单:

class PostcodeForm(forms.Form):
    postcode = forms.CharField(required=True, widget=forms.TextInput(
        attrs={
            'placeholder': "enter a postcode",
        }
    ))

    def clean(self):
        postcode = self.cleaned_data.get('postcode', '')
        print('clean_postcode', postcode)
        if postcode != 'something':
            raise forms.ValidationError(_("Please enter a valid postcode"), code='invalid')
        return super(PostcodeForm, self).clean()

答案 2 :(得分:0)

每当您处理发布数据的有效性时,请务必在views.py中包含 form.is_valid()条件。