我想在我的网页中随处放置一个登录表单,因此我添加了context_processor
并将其包含在base.html文件中。现在的问题是我看不到表格。
这是我的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}
以下是我在base.html尝试调用表单时尝试的差异htmls:
<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}
(因为formLogin
是LoginForm()
)但我在检查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 :(得分: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)
答案 1 :(得分:4)
我认为OP错误地认为模板上下文变量将匹配上下文处理器的函数名。
OP的上下文处理器global_login_form()
将formLogin
注入模板上下文。因此,在模板中,表单应该被引用为,例如{{ formLogin.as_p }}
。
答案 2 :(得分:3)
我想在我的网站上随处使用给出一个信号,表明您可能需要模板上下文处理器。
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),
)
答案 3 :(得分: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 :(得分:0)
不要试图把POST没有真正发布的东西放进去。如果您需要获取模板标签的一些信息,只需使用上下文。
答案 5 :(得分:0)
最后,我使用中间件来处理请求,而不是使用context_processor。此外,我删除了我的登录视图,并将表单操作更改为“。”所以登录功能在中间件中。
我跟着this question找到了解决方案。