在 Django 中自动将注销/ URL 路由到登录/

问题描述 投票:0回答:1

我正在按照教程使用 Python 和 Django 构建待办事项列表, 我已经使用内置视图完成了身份验证和基于用户的访问的实现,

单击“注销”按钮后,我会正确重定向到登录页面。 但是,如果我直接在 url 中输入 http://localhost:8000/logout ,则会显示 405 错误。 我的目标是如果有人直接输入登录页面的网址,则重定向用户。 我该怎么做?

下面是我的 url.py 文件

from django.urls import path, reverse_lazy
#from . import views                 # For Functions, thus but now it's class so 
from .views import TaskList, TaskDetail, TaskCreate, TaskUpdate, TaskDelete, CustomLoginView, RegisterPage         # CLASSES FROM VIEWS FILES 
from django.contrib.auth.views import LogoutView

urlpatterns = [
    path('login/',CustomLoginView.as_view(),name='login'),
    path('logout/',LogoutView.as_view(next_page=reverse_lazy('login')),name='logout'),
    path('register/', RegisterPage.as_view(),name="register"),


    path('', TaskList.as_view(), name='tasks'),                             # root URL - #base url thus empty string, view name
    path('task/<int:pk>', TaskDetail.as_view(), name='task'),               # when clicked on list item - sub url <int:pk> - pk - primary key  
    path('create-task/', TaskCreate.as_view(), name='task-create'),         # url accessed to create the task
    path('update-task/<int:pk>', TaskUpdate.as_view(), name='task-update'),         # url accessed to update the task
    path('delete-task/<int:pk>', TaskDelete.as_view(), name='task-delete'),         # url accessed to delete the task
]

下面是我的相关view.py函数

from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView  #description pane
from django.views.generic.edit  import CreateView, UpdateView, DeleteView, FormView   # create form; update  prefill and modify the data
from django.urls import reverse_lazy                # redirects user to certain part or page

from django.contrib.auth.views import LoginView                 
from django.contrib.auth.mixins import LoginRequiredMixin       #add this before builtin view to prevent unauthorised user accessing data, 
from django.contrib.auth.forms import UserCreationForm          #built in user creation
from django.contrib.auth import login                           #to login user automatically once registered

from .models import Task

# Create your views here.
#if not logged in then restrict people from seeing it 
#gatekeeper thus on top - login optionality 

class CustomLoginView(LoginView):
    template_name = 'base/login.html'
    fields = '__all__'
    redirect_authenticated_user = True                     #--- unauthenticated users to be redirected 
    def get_success_url(self):
        return reverse_lazy('tasks')


class RegisterPage(FormView):
    template_name = 'base/register.html'                         
    form_class = UserCreationForm                           #--- passing prebuilt form
    redirect_authenticated_user = True
    success_url = reverse_lazy('tasks')                     #--- redirect on success when registered

    def form_valid(self, form):                         #-- the form submission is valid by rules
        user = form.save()                              #-- save the user
        if user is not None:                            #-- is user is suceesfully created
            login(self.request, user)                   #-- redirect control to login function for autologin
        return super().form_valid(form)
    
    def get(self,*args, **kwargs):
        if self.request.user.is_authenticated:          
            return redirect('tasks')                    
        return super().get(*args,**kwargs)              

下面是整个应用程序中注销按钮的放置位置

task_list.html

<!-- homepage tasks listing  -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>To Do</title>
</head>
<body>
    
    {% if request.user.is_authenticated %}
    <p>{{ request.user }}</p>

    <!-- <a href="{% url 'logout' %}">Log Out</a>   Won't work error 405, need POst and csrf token by django -->

    <form action="{% url 'logout' %}" method="post">
        {% csrf_token %}
        <button type="submit">Logout</button>
    </form>
    {% else %}
    <a href="{% url 'login' %}">Log In</a>
    {% endif %}

    <hr>
    <h1>My To Do List</h1>
    <a href="{% url 'task-create' %}"> Add Items</a>
    <table>
        <tr>
            <th>Items</th>              <!-- th acts as cell header -->
            <th> </th>                  <!--   #td only shows if we've a th for each td-->
            <th> </th>
            <th> </th>
        </tr>
        <!-- loop through all the items  -->
        {% for task in tasks %}   <!-- this si django templating syntax-->
        <tr>
            <td>{{task.title}}</td>                                     <!-- td acts as cell value -->
            <td><a href="{% url 'task' task.id %}">View</a></td>
            <td><a href="{% url 'task-update' task.id %}">Edit</a></td>
            <td><a href="{% url 'task-delete' task.id %}">Delete</a></td>
        </tr>
        {% empty %}
        <h3>No Items in List</h3>
        {% endfor %}
    </table>
</body>
</html>

我尝试过搜索,但到处都只提到了下面的解决方案,并且仅针对专用按钮。没有关于如何处理 localhot:8000/logout url 的解决方案

<form action="{% url 'logout' %}" method="post">
        {% csrf_token %}
        <button type="submit">Logout</button>
</form>
python django http-redirect django-views django-urls
1个回答
0
投票

基于

Django
LogoutView

的源代码

class LogoutView(RedirectURLMixin, TemplateView):
    """
    Log out the user and display the 'You are logged out' message.
    """

    http_method_names = ["post", "options"]
    template_name = "registration/logged_out.html"
    extra_context = None

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

    def post(self, request, *args, **kwargs):
        """Logout may be done via POST."""
        auth_logout(request)
        redirect_to = self.get_success_url()
        if redirect_to != request.get_full_path():
            # Redirect to target page once the session has been cleared.
            return HttpResponseRedirect(redirect_to)
        return super().get(request, *args, **kwargs)

链接在这里:https://github.com/django/django/blob/main/django/contrib/auth/views.py

此视图不会处理

GET
请求,当您调用它时,将返回
405 Method Not Allowed

所以如果你真的需要这样做,你必须编写自己的

Logout
视图。

© www.soinside.com 2019 - 2024. All rights reserved.