0

I have a custom validator which should raise an error on the frontend for the user if the validation fails. However, I am not sure where and how to return this to the frontend. Right now it only shows in the terminal/Django error site on dev server:

The view:

def raise_poller(request):
    # if this is a POST request we need to process the form data
    if request.method == 'POST':

        # create a form instance and populate it with data from the request:
        form = PollersForm(request.POST)

        # check whether it's valid:
        if form.is_valid():

            # Make Validation of Choices Fields
            poller_choice_one = form.cleaned_data['poller_choice_one']
            poller_choice_two = form.cleaned_data['poller_choice_two']

            if ' ' in poller_choice_one or ' ' in poller_choice_two:
                raise ValidationError('Limit your choice to one word', code='invalid')

                return poller_choice_two  # !! IDE says this is unreachable

            else:

                # process the remaining data in form.cleaned_data as required

                poller_nature = form.cleaned_data['poller_nature']
                poller_text = form.cleaned_data['poller_text']
                poller_categories = form.cleaned_data['poller_categories']

                # Get the user
                created_by = request.user

                # Save the poller to the database
                p = Pollers(poller_nature=poller_nature,
                            poller_text=poller_text,
                            poller_choice_one=poller_choice_one,
                            poller_choice_two=poller_choice_two,
                            created_by=created_by)
                p.save()
                p.poller_categories.set(poller_categories)

                # redirect to a new URL:
                return HttpResponseRedirect('/')

    # if a GET (or any other method) we'll create a blank form
    else:
        form = PollersForm()

    return render(request, 'pollinator/raise_poller.html', {'form': form})

template

{% block content %}

    <div class="poll-container">

        <form action="/raisepoller/" method="post">
            {% csrf_token %}
            {{ form }}
            <input type="submit" value="Submit">
        </form>
    </div>
    
{% endblock %}

Also where to best structure/implement custom validators? After the if form.is_valid part?

5
  • Can you show how you render the form in the template? Commented Sep 3, 2021 at 18:56
  • Ah, but you need to do the validation in the Form, not in the view. Commented Sep 3, 2021 at 19:19
  • oh lol...that makes sense Commented Sep 3, 2021 at 19:20
  • @WillemVanOnsem so adding the validator into the form means if form.is_valid then considers my own validator within the form? Commented Sep 3, 2021 at 19:22
  • yes, like the answer of yedpodtrzitko. You implement this in the clean method. Commented Sep 3, 2021 at 19:26

1 Answer 1

2

To show the error in the form, you have to raise the ValidationError in the form (instead of the view), because form expects and handles when ValidationError is eventually raised. Read the docs about forms validation here

class PollersForm(forms.Form):
  
    def clean(self):
       data = self.cleaned_data
       poller_choice_one = data['poller_choice_one']
       poller_choice_two = data['poller_choice_two']

       if ' ' in poller_choice_one or ' ' in poller_choice_two:
           # raising ValidationError here in clean does the trick
           raise ValidationError('Limit your choice to one word', code='invalid')
       return data

sidenote: if the only thing you are doing with the form is creating a model instance, you should consider using ModelForm instead, which is designed exactly for this purpose. It will save you writing a lot of code.

Sign up to request clarification or add additional context in comments.

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.