【问题标题】:django - middleware issuedjango - 中间件问题
【发布时间】:2012-03-22 20:40:35
【问题描述】:

我想在我的网站上随处放置一个登录表单,在遵循一些 SO 答案后,我决定编写自己的中间件,如下所示:

class LoginFormMiddleware(object):
'''
Put a login form in everypage of the website
'''
def process_request(self, request):
    # if the top login form has been posted
    if request.method == 'POST': 
        if 'logout_submit' in request.POST:
            # log the user out
            from django.contrib.auth import logout
            logout(request)
            form = LoginForm()
        elif 'login_submit' in request.POST:
            # validate the form
            form = LoginForm(data=request.POST)
            if form.is_valid():
                # log the user in
                from django.contrib.auth import login
                login(request, form.get_user())
        else:
            form = LoginForm(request)
    else:
        form = LoginForm(request)
    # attach the form to the request so it can be accessed 
    # within the templates
    request.login_form = form

在我的 settings.py 中,我有:

import django.conf.global_settings as DEFAULT_SETTINGS
...
MIDDLEWARE_CLASSES = DEFAULT_SETTINGS.MIDDLEWARE_CLASSES + (
    'base.mymiddleware.LoginFormMiddleware',
)
TEMPLATE_CONTEXT_PROCESSORS = DEFAULT_SETTINGS.TEMPLATE_CONTEXT_PROCESSORS + (
    'django.core.context_processors.request',
)

base.html 中要从任何地方访问的表单如下所示:

{% if user.is_authenticated %}
            <div class="login_box">
                <form action="/myapp/logout/" method="post">{% csrf_token %}
                    <div class="col2"><a>{{ user.username }}</a></div>
                    <div class="col3"><input type="submit" value="Logout" name="logout_submit"/></div>
                </form>
            </div>
        {% else %}
                <form action="." method="post">
                    {% csrf_token %}
                    <div class="login_box">
                        <div class="error_box">
                            {% if request.login_form.errors %}
                                Incorrect User/Password
                            {% endif %}
                        </div>
                        <div class="col00"> <h4>{{ request.login_form.username.label_tag }}</h3></div>
                        <div class="col11">{{ request.login_form.username }}</div>
                        <div class="col22"><h4>{{ request.login_form.password.label_tag }}</h3></div>
                        <div class="col33">{{ request.login_form.password }}</div>
                        <div class="col44"><input type="submit" value="Login" name="login_submit"/></div>
                        <input type="hidden" name="next" value="{{ request.get_full_path }}" />
                    </div>
                </form>
        {% endif %}

登录工作正常,但是在完成之后,每次我发出 GET 请求 user.is_authenticated 似乎都返回 false,因为我看到的是一个空的 LoginForm 而不是注销表单。

我不知道问题是否出在我的中间件上(当 request.method != 'POST' 它返回 form = LoginForm(request))或者是我的设置中缺少的东西,或者可能为此使用中间件不是个好主意...

【问题讨论】:

  • 也请添加您的相关视图。我个人不明白在这种情况下使用中间件的目的,Django 提供了一个不错的模块用于登录和注销。
  • 我的观点并没有多大作用,因为所有的工作都在中间件中,事实上,我在里面使用了 django 登录。登录和注销视图只有这一行:return HttpResponseRedirect(request.META.get('HTTP_REFERER'))。使用中间件的好处是因为我希望这个表单在我的站点中无处不在,而不是在 HTML 中
  • Django 的 auth 中间件已经将 user 对象添加到模板中的 dict 中,如果您使用模板继承(应该),您可以将base.html 中的表单,这样它将在每个页面上加载

标签: django forms authentication middleware


【解决方案1】:

我不敢相信您已经看到任何主张将这种逻辑放入中间件的 SO 答案。 (如果有,请发布链接,以便我对它们投反对票。)

这真的,真的,真的不是做这种事情的地方。编写特定视图并将登录表单的操作参数设置为该视图。

但是,我怀疑您的根本问题是您没有使用 RequestContext 来呈现其他视图,因此用户对象没有传递给模板。

【讨论】:

  • @juankysmith 这就是为什么我们有@login_required装饰器
  • 抱歉我的无知,但我看不到装饰器与每次查看后显示表单的事实之间的关系
【解决方案2】:

您的实现没有多大意义。具有动作属性的登录表单是“。”是错误的,会导致冲突。

你应该有一个登录view,而不是一个登录middleware。登录表单的 action 属性应该是登录视图的反向 url。

在您的登录表单中,您应该指定下一个隐藏输入,例如:

<input name="next" type="hidden" value="{{ request.POST.next|default:request.path }}" />

然后,它可以在您的基本模板中或网站的任何位置。

这对注销也有效。

【讨论】:

  • 所以...我必须在每个视图的返回中传递表单吗??
  • 你为什么要这样做?只需粘贴表单的 HTML。这就是我们在 betspire.com 上所拥有的,它简单明了。
  • 是的,我想做的是像 betspire's 这样的登录。它是否使用视图进行登录?
  • 是的,/account/login/。但是基本模板允许用户从任何页面被引导到这个页面。
  • 这个视图的回报如何?
猜你喜欢
  • 1970-01-01
  • 2010-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-11
  • 1970-01-01
相关资源
最近更新 更多