django - проблема промежуточного программного обеспечения - PullRequest
0 голосов
/ 05 марта 2012

Я хочу разместить форму входа на своем веб-сайте повсюду, после нескольких ответов 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' возвращает форму = LoginForm (запрос)), или это то, что мне не хватает в моих настройках, или, возможно, использование промежуточного программного обеспечения для этого было не очень хорошая идея ...

Ответы [ 2 ]

1 голос
/ 05 марта 2012

Я не могу поверить, что вы видели какие-либо SO-ответы, которые выступают за использование такой логики в промежуточном программном обеспечении. (Если есть, опубликуйте ссылку, чтобы я мог понизить их рейтинг.)

Это действительно, действительно, действительно не место, чтобы делать подобные вещи. Напишите конкретное представление и установите для этого параметра параметр действия формы входа в систему.

Однако я подозреваю, что ваша основная проблема заключается в том, что вы не используете RequestContext для визуализации других представлений, поэтому объект пользователя не передается в шаблон.

0 голосов
/ 05 марта 2012

Ваша реализация не имеет особого смысла. Форма входа с атрибутом действия - "." неправильно и приведет к конфликтам.

У вас должен быть логин view , а не логин middleware . Атрибутом действия формы входа в систему должен быть обратный URL-адрес вашего вида входа в систему.

В форме входа в систему вы должны указать следующий скрытый ввод, например:

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

После этого он может быть в вашем базовом шаблоне или в любом месте на сайте.

Это также верно для выхода из системы.

...