Crispy Form VariableDoesNotExist on Django

dman picture dman · Dec 20, 2013 · Viewed 8.6k times · Source

For crispy form on Django, I keep getting VariableDoesNotExist at / Failed lookup for key [form] in u'[{\'False\': False, \'None\': None,.....

{% extends 'base.html' %}
{% load crispy_forms_tags %}

{% block loginForm %}
    <div class="container" style="padding-bottom: 70px;">
        <div class='row'>
            <div class='col-md-6 col-md-offset-3'>
                <div class="well">
                    <legend>Sign in</legend>
                    <form method="post" action="{% url 'django.contrib.auth.views.login' %}" class="form-horizontal">
                        {% crispy form %}
                        <input type="hidden" name="next" value="{{ next }}"/>
                    </form>
                </div>
            </div>
        </div>
    </div>

{% endblock loginForm %}

forms.py:

from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Div, Submit, HTML, Button, Row, Field, Hidden, Fieldset
from crispy_forms.bootstrap import AppendedText, PrependedText, FormActions
from django.contrib.auth.forms import AuthenticationForm


class LoginForm(AuthenticationForm):
    def __init__(self, *args, **kwargs):
        super(LoginForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-lg-2'
        self.helper.field_class = 'col-lg-8'
        self.helper.form_tag = False
        self.helper.layout = Layout(
            Field('username', placeholder="username", css_class='input-xlarge'),
            Field('password', placeholder="Password", css_class='input-xlarge'),
            FormActions(
                Submit('login', 'Login', css_class="btn-primary"),
            )
        )

I don't understand, because according to documentation I am using FormHelper on attribute helper so I should be able to use {% crispy form %}

Answer

sk1p picture sk1p · Dec 20, 2013

The first argument to the crispy template tag is the name of the context variable where Crispy Forms expects the Form instance. So you need to somehow get a Form instance in your template context. If you were using this form in a view, you could do something like

def yourview(request):
    return TemplateResponse(request, "yourtemplate.html", {'form': LoginForm()})

If you want to have that form on many different pages, I'd suggest an inclusion tag:

@register.inclusion_tag('path/to/login_form.html')
def display_login_form():
    return {'form': LoginForm()}

And in your template:

{% load your_template_tags %}
{% display_login_form %}

(see also the usual setup procedure for custom template tags)