Django - сбой настройки вида выхода из системы - PullRequest
1 голос
/ 17 февраля 2020

Хотя исходный вопрос прояснен, есть новый связанный вопрос, который довольно интересен: (пожалуйста, дайте мне знать, если моя теория верна дистанционно ...)

Пожалуйста, ознакомьтесь с моими urlpatterns ниже:

from django.contrib.auth import views as auth_views
from boutique.models import Category
from django.urls import path, include
from . import views

app_name = 'users'
urlpatterns = [

    # to customise login view
    path('login/', auth_views.LoginView.as_view(extra_context = {'categories': Category.objects.get_categories_with_item()})),
    # path('login/', views.NewLoginView.as_view()),

    # to customise default logout view
    path('logout/', auth_views.LogoutView.as_view(), {'categories': Category.objects.get_categories_with_item()}),

    # include django authentication urls
    path('', include('django.contrib.auth.urls')),

Поскольку вы, вероятно, заметили, что есть два разных способа передачи в extra_context, интересно то, что: метод, используемый в LogoutView, нельзя использовать в LoginView !! Тем не менее, метод, используемый на LoginView, работает на LogoutView.

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

LoginView:

class LoginView(SuccessURLAllowedHostsMixin, FormView):
    """
    Display the login form and handle the login action.
    """
    form_class = AuthenticationForm
    authentication_form = None
    redirect_field_name = REDIRECT_FIELD_NAME
    template_name = 'registration/login.html'
    redirect_authenticated_user = False
    extra_context = None

    ...

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        current_site = get_current_site(self.request)
        context.update({
            self.redirect_field_name: self.get_redirect_url(),
            'site': current_site,
            'site_name': current_site.name,
            **(self.extra_context or {})
        })
        return context

LogoutView:

class LogoutView(SuccessURLAllowedHostsMixin, TemplateView):
    """
    Log out the user and display the 'You are logged out' message.
    """
    next_page = None
    redirect_field_name = REDIRECT_FIELD_NAME
    template_name = 'registration/logged_out.html'
    extra_context = None

    ...

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        current_site = get_current_site(self.request)
        context.update({
            'site': current_site,
            'site_name': current_site.name,
            'title': _('Logged out'),
            **(self.extra_context or {})
        })
        return context

Я думаю, причина того, что LoginView должен передать extra_context в качестве позиционного аргумента в .as_view(), заключается в том, что он не наследуется от TemplateView:

class TemplateView(TemplateResponseMixin, ContextMixin, View):
    """
    Render a template. Pass keyword arguments from the URLconf to the context.
    """
    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
        return self.render_to_response(context)

, который имеет метод get для получения данных контекста ... если я не ошибаюсь.

Кто-нибудь может это подтвердить?

Я довольно новичок в python и django framework. Большое спасибо !!!


На оригинальный вопрос дан ответ

Пожалуйста, ознакомьтесь с ответами в комментариях -


Я довольно новичок в Django и чтобы перейти в более широкий контекст к представлению выхода из системы, я попытался 2 способа настроить представление выхода из системы:

Метод 1:

from django.contrib.auth import views as auth_views
from boutique.models import Category

app_name = 'users'
urlpatterns = [
    ...
    path('logout/', auth_views.LogoutView.as_view(), {'categories': Category.objects.all()}),

    # I also tried this:
    # path('logout/', auth_views.LogoutView.as_view({'categories': Category.objects.all()}),


    # I also tried this: 
    # path('logout-customised-url/', auth_views.LogoutView.as_view(), {'categories': Category.objects.all()}),
    # This is working tho it wouldn't be automatically redirect to this path when logged out

Метод 2:

    ...
    path('logout/', views.NewLogoutView.as_view()),
    # NewLogoutView code below:

views.py

from boutique.models import Category
from django.contrib.auth.views import LogoutView


class NewLogoutView(LogoutView):

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['categories'] = Category.objects.all()
        return context

Все еще не работает, и результат точно такой же: если используется настроенный URL-адрес, такой как 'logged-out /' вместо 'logout /', и вы вводите URL, он отображает правильную страницу с дополнительным контекстом. Однако не будет go до страницы, когда пользователи выходят из системы нормально ...

Есть ли обходной путь? Спасибо!

Ответы [ 2 ]

0 голосов
/ 17 февраля 2020

Понял !! Проблема была в порядке моих urlpatterns, изначально это было так:

urlpatterns = [

    # include django authentication urls
    path('', include('django.contrib.auth.urls')),

    # to customise default logout view
    path('logout/', auth_views.LogoutView.as_view(), {'categories': Category.objects.get_categories_with_item()}),

На основе official do c: представления аутентификации , django.contrib.auth.urls включает в себя множество шаблонов url, такие как:

accounts/login/ [name='login']
accounts/logout/ [name='logout']
accounts/password_change/ [name='password_change']
accounts/password_change/done/ [name='password_change_done']
accounts/password_reset/ [name='password_reset']
accounts/password_reset/done/ [name='password_reset_done']
accounts/reset/<uidb64>/<token>/ [name='password_reset_confirm']
accounts/reset/done/ [name='password_reset_complete']

Следовательно, они имеют приоритет, если они были объявлены до настройки. Итак:

urlpatterns = [

    # to customise default logout view
    path('logout/', auth_views.LogoutView.as_view(), {'categories': Category.objects.get_categories_with_item()}),


    # include django authentication urls
    path('', include('django.contrib.auth.urls')),

Чтобы обменять ордер, он работает.


Для таких новичков, как я: Метод 1 работает. Просто передайте дополнительный контекст / аргумент, как указано в официальном do c после представления.

Также я проверил django.contrib.auth.views.LogoutView:

class LogoutView(SuccessURLAllowedHostsMixin, TemplateView):
    """
    Log out the user and display the 'You are logged out' message.
    """
    next_page = None
    redirect_field_name = REDIRECT_FIELD_NAME
    template_name = 'registration/logged_out.html'
    extra_context = None
    ...

extra_context установлен на None для добавления дополнительного контекста. Легко настроить, если бы он был подклассом или просто передал позиционный аргумент в .as_view() - что означает:

urlpatterns = [

    # to customise login view
    path('login/', auth_views.LoginView.as_view(extra_context = {'categories': Category.objects.get_categories_with_item()})),

]

`Loginview` has the same the same convenient settings...

0 голосов
/ 17 февраля 2020

Вам нужно передать extra_context в вашем urls.py порядке, чтобы отправить дополнительный контекст для вида выхода из системы. подробнее о передаче дополнительного контекста представлению в определении URL .

path(
    'logout/',
    auth_views.LogoutView.as_view(),
    {'extra_context':{'categories': Category.objects.all()}}
),
...