0

I'm using Django 2.0. This is my 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

And my views.py:

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

And my 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>

But when I type in any value other than 'something', the form still submits. I also don't see any print statements in the console, so it looks as though the validator just isn't being run.

What am I doing wrong?

4
  • Can you show the code of the view you are calling through the url "lookup_postcode"? Commented Apr 12, 2018 at 10:00
  • try form.isvalid() Commented Apr 12, 2018 at 10:00
  • 4
    you have used self.clean_data in form is it typo?? I believe you need to use self.cleaned_data and what's the data you returned with return data Commented Apr 12, 2018 at 10:02
  • 1
    Are you making the GET request to PostcodeForm ? Commented Apr 12, 2018 at 10:04

3 Answers 3

5

At the moment you are always doing form = PostcodeForm(), for GET and POST requests. That means that the form is not bound to any data, so it will never be valid or have any errors.

In Django, a typical view to process a form looks something like this:

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)

For this to work, you'll need to change your form method to 'post'.

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

If you keep the form method as 'get' then you'll need to bind the form to request.GET instead. You might want to add a check, otherwise you'll get errors for required fields when you first access the index view.

if 'postcode' in request.GET:
    # bound form
    form = PostcodeForm(request.GET)
else:
    # unbound, empty form
    form = PostcodeForm()
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! For the benefit of others, I used form.add_error() to add custom errors as required.
0

Use your form as below:

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()

Comments

0

Everytime you deal with the validity of the posted data, make sure to include form.is_valid() condition in your views.py.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.