Django crispy forms error message

8.1k Views Asked by At

I am very new to Python and django. And I am currently having an issue I cannot overcome. I have tried reading all the docs and googling, but nothing so far.

I have a very custom login form I need to use. All the code is there are works so far. I just want to authenticate the user (which works fine), but if they enter the incorrect details, I want to show an error message on the form saying invalid login details instead of returning an HttpResponse, but I cannot seem to figure out how exactly to display an auth error like this on a crispy form like this.

Any help would be much appreciated

Oh yes, and this is python 3.4 if that makes any difference

This is my forms.py:

class UserLoginForm(forms.ModelForm):
    email = forms.CharField(
        label="Your email address",
        max_length=80,
        required=True,
    )

    password = forms.CharField(
        label="Your password",
        required=True,
    )

    def __init__(self, *args, **kwargs):
        super(UserLoginForm, self).__init__(*args,**kwargs)

        self.helper = FormHelper(self)
        self.helper.form_id = 'form-login'
        self.helper.form_class = 'form-login'
        self.helper.form_method = 'POST'
        self.helper.form_action = 'login'
        self.helper.field_class = 'form-control input-lg'
        self.helper.form_show_errors = True
        self.helper.layout = Layout(
            Field('email', template='crispy/login_input_email.html'),
            Field('password', template='crispy/login_input_password.html'),
        )

        self.helper.layout.append(Submit('login', 'Log me in', css_class='btn btn-primary btn-lg'))

    class Meta:
        model = User
        fields = ('email', 'password',)

This is my views.py:

def login_view(request, template_name='login.html'):

    redirect_url = request.GET.get('next')

    if request.method=='POST':
        loginForm = UserLoginForm(request.POST)
        if loginForm.is_valid():

            username = loginForm.cleaned_data.get('email')
            password = loginForm.cleaned_data.get('password')

            user = authenticate(username=username, password=password)
            if user is not None:
                if redirect_url is None:
                    redirect_url='/home'

                login(request, user)
                return HttpResponseRedirect(redirect_url)
            return HttpResponse("Invalid login details supplied.")
        return render_to_response(template_name, {'crispy_form': loginForm}, context_instance=RequestContext(request))
    else:
        loginForm = UserLoginForm()
    return render_to_response(template_name, {'crispy_form': loginForm}, context_instance=RequestContext(request))

And lastly, this is my template:

{% extends "master.html" %}

{% load crispy_forms_tags %}

{% block content %}
   <div class="inner-block">
        <h1>Log in to your account</h1>
        {% crispy crispy_form crispy_form.helper %}
  </div>
{% endblock %}

Thanks

2

There are 2 best solutions below

1
On BEST ANSWER

Use the messaging system

from django.contrib import messages

...
else:
    messages.error(request, "Your error message")
    loginForm = UserLoginForm()
....

Check on the django.contrib.messagges doc.

0
On

You may also want to check and see if you are getting the HTML5 required attribute added to the form element tags for the elements that you have defined as required in your models.py.

If you are, and required elements are missing from your form, the HTML5 client-side validation in your browser prevents the form submitting, so you don't get a request.POST and so no Django server-side validation and thus no form.errors are returned.

I spent a good few days puzzling out this one. Anyways, starting with Django 1.10, you can turn off the HTML5 required attribute in the form elements* and rely on the server-side Django validation (and template error messages).

*In my testing the HTML5 form validation bubble support was hit/miss and I have users in locked down machines who may not have the latest, greatest browser version.