gpt4 book ai didi

python - Django 上下文处理器和 csrf_token

转载 作者:太空宇宙 更新时间:2023-11-03 11:05:22 26 4
gpt4 key购买 nike

我有一个登录表单,我希望它在我的所有 View 中都可用,因此我创建了一个上下文处理器来将此表单添加到每个加载的上下文中。

问题是 {% csrf_token %}在表单模板上不会呈现具有 CSRF token 值的隐藏输入标签。

这是 settings.py 中的上下文处理器顺序:

TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.core.context_processors.tz',
'django.contrib.messages.context_processors.messages',
'django.core.context_processors.request',
'django.core.context_processors.csrf',
'absolute.context_processors.absolute',
'myproject.app.context_processors.base',
)

然后处理器本身在 app/context_processors.py 上:

from django.contrib.auth.forms import AuthenticationForm

def base(request):
context = dict()
if not request.user.is_authenticated():
context['login_form'] = AuthenticationForm()
return context

表单模板:

{% load i18n %}

<form method="post" action="{% url "django.contrib.auth.views.login" %}">

{% csrf_token %}
<input type="hidden" name="next" value="{% if request.GET.next %}{{ request.GET.next }}{% else %}{{ request.get_full_path }}{% endif %}" />

{{ login_form.as_p }}

<input type="submit" class="button success expand" value="{% trans 'Login' %}" />

</form>

此表单的 HTML 输出:

<form action="/accounts/login/" method="post">


<input type="hidden" value="/" name="next">

<p><label for="id_username">Usuário:</label> <input type="text" name="username" maxlength="254" id="id_username"></p>
<p><label for="id_password">Senha:</label> <input type="password" name="password" id="id_password"></p>

<input type="submit" value="Login" class="button success expand">

</form>

提交时出现的错误:

CSRF verification failed. Request aborted.

但是,由于我只使用基于类的 View ,如果我添加 csrf_protect decorator 表单将工作,但像这样我必须声明 dispatch我所有观点中的方法:

from django.views.decorators.csrf import csrf_protect

class HomeView(TemplateView):
template_name = 'home.html'

@method_decorator(csrf_protect)
def dispatch(self, *args, **kwargs):
return super(HomeView, self).dispatch(*args, **kwargs)

问题状态

我放弃了通过创建登录表单页面将 AuthenticationForm 放在我的所有 View 中。不管怎样,如果有人能帮我找到解决这个问题的方法,那还是很棒的。

最佳答案

我花了几个小时来解决与您在此处描述的问题类似的问题。 {% csrf_token %} 没有渲染任何东西,我在 Debug模式下看到了这个:

defaulttags.py:66: UserWarning: A {% csrf_token %} was used in a template, but the context did not provide the value. This is usually caused by not using RequestContext.

我使用的是从 TemplateView 继承的简单 View :

class MenuIndexView(TemplateView):
template_name = 'menu/index.html'

def get_context_data(self, **kwargs):
kwargs = super().get_context_data(**kwargs)

session = self.request.session
kwargs['zip_code'] = session.get('zip_code')
kwargs['calendar'] = helpers.get_menu_calendar(date.today() + timedelta(days=1), timedelta(days=14))
kwargs['forms'] = {'zip_code': forms.ZipCodeForm({'zip_code': session.get('zip_code')})}

return kwargs

在 Django 下大惊小怪之后,我意识到在生成标签的地方几乎没有可用的上下文(Django 的 defaulttags.py 文件上的 CsrfTokeNode) :

class CsrfTokenNode(Node):
def render(self, context):
csrf_token = context.get('csrf_token', None)
if csrf_token:
if csrf_token == 'NOTPROVIDED':
return format_html("")
else:
return format_html("<input type='hidden' name='csrfmiddlewaretoken' value='{}' />", csrf_token)
else:
# It's very probable that the token is missing because of
# misconfiguration, so we raise a warning
if settings.DEBUG:
warnings.warn(
"A {% csrf_token %} was used in a template, but the context "
"did not provide the value. This is usually caused by not "
"using RequestContext."
)
return ''

在这段代码中,我只看到上下文中的一个项目,带有 zip_code 键。

我打开主模板文件并意识到我犯了一个新手错误 - 这是我的主模板 menu/index.html:

{% extends 'base.html' %}

{% block content %}
<div class="menu-order-meta zip_calendar">
<div class="ink-grid align-center">
<div class="column-group gutters half-vertical-padding medium">
{% include 'partials/menu/zip-code.html' with zip_code=zip_code only %}
</div>
</div>
</div>
{% endblock %}

我通过部分模板包含表单,并且我明确限制了该部分模板中的可用上下文 - 注意 with zip_code=zip_code only 声明 -(并且通过这样做,隐式地将csrf_token 上下文处理器不可用)。

关于python - Django 上下文处理器和 csrf_token,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20985180/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com