开发者

Django: How to include modelform?

{% include 'django.contrib.auth.views.login' %}

I don't want to write everything by hand.. I hate this really, django full of automatic stuff.

Goal is to include registration/login.html into base.html, so that I could have this form in every page

If I include only template itself (registration/login.html), problem appears t开发者_开发问答hat "form.login", I mean "form" var is not defined because this one comes from VIEW which called when you going to login url. So how can I call that view MANUALLY with include or at least to grab django.contrib.auth.views.login variables by my self in my own view and pass then to base.html?

P.s. It's not just about login form, I think there will be more situations like this


I have found better solution in #django irc.

They called inclusion tags

I'll give you my code, because I got lot's of problem learning new stuff in django =)

file: templatetags/form_login.py

from django import template
register = template.Library()

from django.contrib.auth.forms import AuthenticationForm

@register.inclusion_tag('registration/login.html')
def form_login():
    return { 'form': AuthenticationForm() }

Now you can have your form anywhere, this will prerender template and THAT'S IT! no stupid context processors which requires to modify whole project settings.py, which is really sux if you writing stand alone little application..


If you need login-form on every page

Create a context processor:

def login_form_processor(request):
    return {
        'login_form': LoginForm(request.POST or None)
    }

Add it to settings.CONTEXT_PROCESSORS.

Include the template for login form:

{% with login_form as form %}
    {% include "registration/login.html" %}
{% endwith %}

You can also make you form lazy-loading, so form will not be created until it is used for the first time.

from django.utils improt functional
def login_form_processor(request):
    create_login_form = lambda: LoginForm(request.POST or None)
    return {
        'login_form': functional.lazy(create_login_form, LoginForm)
    }

But I guess you won't want the lazy-loading feature, because login-form is cheap to initialize.


Reusing views

Concerning the "grabbing variables" part from your question: you cannot grab variable from view. Django view is method which returns response object. You can not get variables from response. However some of views accept extra_context and other attributes. Those attributes allow you to configure those views in urls, or to wrap them with your own view, for example:

def my_login_view(request):
    some_extra_data = get_some_data()
    extra_context = {
        'some_extra_var': some_extra_data
    }
    return login_view(request, extra_context=extra_context, template="my_template.html")

This is not exactly grabbing the variables from views, more like augmentation of existing views.

If you expect to have more situations like this, do less data-porcessing in views. Call some methods which checks for permissions. Collect some data from context-processors. Return rendered response. Now you can reuse the data in other views.


You can specify the action on the form html to point to the URL that accesses the corresponding view.

If you want a form, say called as login_form always populated in all templates, then put it in the context_processors.


Browsing the code for django.contrib.auth.views, you will see that the variables form, site and *site_name* are passed to the template.

Either you (1) provide your custom registration form or (2) you can just import django.contrib.auth.forms.AuthenticationForm in your view if you want to use it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜