Помещение django входит в форму на каждой странице

Я хотел бы, чтобы форма входа в систему (AuthenticationForm от django.contrib.auth) появилась на каждой странице в моем сайте, если пользователь не зарегистрирован. Когда пользователь войдет в систему, они будут перенаправлены к той же странице. Если будет ошибка, то ошибку покажут на той же странице с формой.

Я предполагаю, что Вам был бы нужен процессор контекста для обеспечения формы каждому шаблону. Но, затем Вам также было бы нужно каждое представление для обработки отправленной формы? Это означает, что необходимо создать некоторое промежуточное программное обеспечение? Я немного потерян.

Существует ли принятый способ сделать это?

46
задан asciitaxi 29 April 2010 в 00:31
поделиться

3 ответа

Хорошо, в конце концов я нашел способ сделать это, хотя уверен, что есть способы лучше. Я создал новый класс промежуточного программного обеспечения под названием LoginFormMiddleware. В методе process_request обрабатывайте форму более или менее так, как это делает представление авторизации:

class LoginFormMiddleware(object):

    def process_request(self, request):

        # if the top login form has been posted
        if request.method == 'POST' and 'is_top_login_form' in request.POST:

            # validate the form
            form = AuthenticationForm(data=request.POST)
            if form.is_valid():

                # log the user in
                from django.contrib.auth import login
                login(request, form.get_user())

                # if this is the logout page, then redirect to /
                # so we don't get logged out just after logging in
                if '/account/logout/' in request.get_full_path():
                    return HttpResponseRedirect('/')

        else:
            form = AuthenticationForm(request)

        # attach the form to the request so it can be accessed within the templates
        request.login_form = form

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

{{ request.login_form }}

Обратите внимание, что скрытое поле 'is_top_login_form' был добавлен в форму, чтобы я мог отличить ее от других размещенных на странице форм. Кроме того, действие формы - "." вместо просмотра авторизации.

34
ответ дан 26 November 2019 в 20:34
поделиться

Самый простой способ, вероятно, заключается в том, чтобы поместить форму вручную в базовый шаблон, например, так:

{% if user.is_authenticated %}
    <form action="{% url login %}" method="POST">{% csrf_token %}
        <input id="username-field" name="username" type="text" />
        <input id="password-field" name="password" type="password" />
        <button type="submit">Login</button>
    </form>
{% else %}
    {# display something else here... #}
{% endif %}

а затем просто написать представление, подключенное к URL с именем "login", чтобы обрабатывать форму, как обычно (используя объект формы, соответствующий вышеупомянутой форме). Пусть представление перенаправляется на request.META['HTTP_REFERER'], чтобы показать его на той же странице, что и отправленная форма.

Такой подход позволяет избежать промежуточного программного обеспечения или необходимости делать форму доступной для каждого отдельного шаблона через контекст.

Обновление: Есть некоторые проблемы с этим подходом; нужно еще немного подумать над ним. Надеюсь, это хотя бы поможет вам двигаться в правильном направлении.

6
ответ дан 26 November 2019 в 20:34
поделиться

Использование django.contrib.auth,вы можете поместить код формы в базовый шаблон следующим образом:

<form method="post" action="{% url auth_login %}">
    {% csrf_token %}
    <p><label for="id_username">Username:</label> <input id="id_username" type="text" name="username" maxlength="30" /></p>
    <p><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /></p>

    <input type="submit" value="Log in" />
    <input type="hidden" name="next" value="" />
</form>

Все, что вам нужно сделать, это изменить следующее значение, поэтому вместо:

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

теперь оно будет:

<input type="hidden" name="next" value="{{ request.get_full_path }}" />

Чтобы получить доступ к объекту запроса, убедитесь, что вы включить

'django.core.context_processors.request'

в обработчики контекста шаблона. Таким образом, вам не нужно писать какие-либо контекстные процессоры для входа в систему, поскольку вы используете встроенные представления Django.

25
ответ дан 26 November 2019 в 20:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: