2011-06-27 16 views
3

我想在我的网页中随处放置一个登录表单,所以我添加了一个context_processor,并将其包含在base.html文件中。现在的问题是我看不到表格。Django - 使用context_processor

这里是我的context_processors.py:

def global_login_form(request): 
    if request.method == 'POST': 
     formLogin = LoginForm(data=request.POST) 
     if formLogin.is_valid(): 
      from django.contrib.auth import login 
      login(request, formLogin.get_user()) 
      ... 
    else: 
     formLogin = LoginForm() 

    return {'formLogin': formLogin} 

这里是diferents HTMLS我base.html文件试图调用形式的尝试:

<form action="/myapp/login/" method="post"> 
{% csrf_token %} 
{{global_login_form}} 
</form> 

<form action="/myapp/login/" method="post"> 
{% csrf_token %} 
{{global_login_form.as_p}} 
</form> 

<form action="/myapp/login/" method="post"> 
{% csrf_token %} 
{{request.formLogin}} 
</form> 

我第一次加载页面, context_process返回{'formLogin': formLogin}(原因formLoginLoginForm())但我在检查html时看不到表单。它不在那里......但我可以看到csrf_token,所以我认为我没有正确调用上下文。

只是它的情况下(也许顺序不正确),这里是settings.py:

TEMPLATE_CONTEXT_PROCESSORS = (
    "myapp.context_processors.global_login_form", 
    "django.core.context_processors.request", 
    "django.contrib.auth.context_processors.auth", 
) 

任何想法?

+0

当你说“无处不在我的网页上”,你实际上意味着“无处不在我的网站”,如你要处处可见,以便用户可以登录每个页面上的登录表单? –

+0

准确,对不起,我的英语 – juankysmith

+0

你能张贴,处理后的看法? 如果我理解正确这个问题,问题是,模板没有POST上下文,所以你不能预先填入失败的形式? –

回答

3

我相信OP错误地认为模板上下文变量将与上下文处理器的函数名匹配。

OP的背景处理器global_login_form()注入formLogin到模板上下文。因此,在模板中,表单应该被引用为例如{{ formLogin.as_p }}

0
class MyForm(forms.Form): 
    username = forms.CharField(widget=forms.TextInput(attrs={'class':'login_text'})) 
    password = forms.CharField(widget=forms.TextInput(attrs={'class':'password_text'})) 

这可能是您的解决方案。 Css作为表单域的一个属性传递,所以你不需要显式地将它声明为你的html。

4

您必须在每个视图中都有表单变量,否则您应该实现一个模板标签。例如:

https://docs.djangoproject.com/en/dev/howto/custom-template-tags/#writing-custom-template-tags

from django import template 
from django.contrib.auth.forms import AuthenticationForm 

register = template.Library() 

@register.inclusion_tag('registration/login.html', takes_context=True) 
def login(context): 
    """ 
    the login form 
    {% load login %}{% login %} 
    """ 
    request = context.get('request', None) 
    if not request: 
     return 
    if request.user.is_authenticated(): 
     return dict(formLogin=AuthenticationForm()) 
    return dict(user=request.user) 
+0

如果您在Firebug中可视化表单,则应该看到{{form.username}}为空。这不是一个CSS问题,但“表单”对象是空的。 – surfeurX

0

不要试图把在POST的东西,并没有真正公布。如果您需要获取模板标签的一些信息,只需使用上下文。

+0

我做到了,我改变了这个问题,现在表格丢失了! – juankysmith

2

我想在我的网站上的任何地方使用给出的信号表明您可能需要模板上下文处理器。

def global_login_form(request): 
    next = request.GET.get('next', '/') 
    login_form = AuthenticationForm(initial={'next': next}) 
    return {'login_form': login_form} 

有了这个,添加这种情况下处理器TEMPLATE_CONTEXT_PROCESSORS节中设置,您可以在您的模板使用{{global_login_form}}

也许你就会有更多或更少的这样的事情

.... 
<form action="{% url login_view_name %}" method="POST"> 
{{global_login_form.as_p}} 
</form> 
.... 

我在项目中的一个使用这种模式,它的工作相当精细。这里只需要注意,如果表单未经过验证,最好在分离的页面上显示错误形式。这里是一个视图的例子:

def login(request): 
    if request.method == "POST": 
     login_form =LoginForm(data=request.POST) 
     if login_form.is_valid(): 
      next = login_form.cleaned_data.get('next', '/') 
      login(request, login_form.get_user()) 
      return HttpResponseRedirect(next) 

    return render_to_response(
     'users/login/login_page.html', 
     {'form': login_form}, 
     context_instance=RequestContext(request), 
     ) 
+0

但是,如果表单没有验证,我希望邮件错误替换登录表单,而不是打开一个不同的页面。这是可行的吗?另一方面,你是否需要使用下一个变量? – juankysmith

+0

你不需要使用下一个变量,这是一个有用的额外。在同一页面上显示表单可能会发布。我想这是最好的使用Ajax响应错误。你需要一个这样的例子吗? – dzida

+2

你的背景处理器的样子:{ 'formLogin':formLogin}所以模板,您可以使用变量{{formLogin}}。 – dzida

0

最后我用中间件来处理请求,而不是使用context_processor。此外,我删除了我的登录视图,并将表单操作更改为“。”所以登录功能在中间件中。

我跟着this question找到解决方案。