Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Include Django login form in base.html

I am new to Django and I would like to include my login form in base html.

I have the following:

"registration/login.html"

{% if form.has_errors %}
    <p>Your username and password didn't match.
        Please try again.</p>
{% endif %}
<form method="post" action=".">
    {% csrf_token %}
    <p><label>Username:</label>
        {{ form.username }}</p>
    <p><label>Password:</label>
        {{ form.password }}</p>
    <input type="submit" value="login" />
    <input type="hidden" name="next" value="/" />
</form>

urls.py

url(r'^login/$', 'django.contrib.auth.views.login'),

And i included in base.html the following:

{% include "registration/login.html" %}

It renders everything except the textboxes for the username and password. I think I am missing something.

like image 935
glarkou Avatar asked Mar 26 '26 20:03

glarkou


1 Answers

OK, the the problem, I think, is you're expecting "magic".

Django's views are templates are pretty dumb. They only have the variables available to them that are passed in one of two ways:

  1. Through a context_processor (see Aidan's answer)
  2. Passed in when calling render (or render_to_response)

The reason the form renders when you visit /login, but in no other case, is because the Django view you're using django.contrib.auth.views.login, passed the Django AuthenticationForm into your template for you.

Review the source here: https://github.com/django/django/blob/master/django/contrib/auth/views.py

No other view "magically" gets that variable set.

So you have to either:

  1. Set it yourself in every view across your whole app
  2. Use a context processor.

Here's an easy context_processors.py which uses the Django stuff (based on Aidan's):

def include_login_form(request):
    from django.contrib.auth.forms import AuthenticationForm
    form = AuthenticationForm()
    return {'login_form': form}

Then, do as Aidan points out:

TEMPLATE_CONTEXT_PROCESSORS = (
    #....
    'yourapp.context_processors.include_login_form'
)

Now, the problem is that, when you just include the template, the login form is in a variable called "login_form", but when django's built-in view uses your template, it's in a variable called "form".

So that's an ordeal without a good "clean" solution, though I'm sure one could sort it out.

Maybe check the context passed in in your context_processor, and if a variable already exists called "form", see if it's an instance of AuthenticationForm, and if it is, use it instead.

like image 177
Jack Shedd Avatar answered Mar 30 '26 08:03

Jack Shedd



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!