上下文
我正在开发一个 Django 项目,在该项目中我使用配置文件和注销功能实现了用户身份验证。我遇到的问题是,当我尝试从导航栏访问个人资料或注销链接时,它会将我重定向到登录页面,而不是导航到用户的个人资料或执行注销。
个人资料链接
应该导航如果用户已登录,则转到用户的个人资料页面。
注销链接
应注销用户并重定向到主页。
当前设置 - 模板 (
base.html
):
{% if logged_in %}
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
{{ customer_name }}
</a>
<ul class="dropdown-menu" aria-labelledby="userDropdown">
<li><a class="dropdown-item" href="{% url 'profile' %}?email={{ customer_email }}">Profile</a></li>
<li><a class="dropdown-item" href="{% url 'logout' %}">Logout</a></li>
</ul>
{% else %}
<a class="nav-link" href="{% url 'login' %}">Login</a>
{% endif %}
视图:| ||URL:
from django.shortcuts import redirect, render
from django.contrib.auth import authenticate, login as auth_login, logout as auth_logout
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .models import customer
@login_required
def profile_view(request):
email = request.GET.get('email')
if email:
try:
user = customer.objects.get(email=email)
if user.id == request.session.get('customer_id'):
return render(request, 'profile.html', {'user': user})
else:
return redirect('index')
except customer.DoesNotExist:
return redirect('index')
else:
return redirect('index')
def logout_view(request):
request.session.flush()
auth_logout(request)
return redirect('index')
def login_view(request):
if request.method == 'POST':
email = request.POST.get('email')
password = request.POST.get('password')
try:
customer = customer.objects.get(email=email)
if customer.check_password(password):
request.session['customer_id'] = customer.id
request.session['logged_in'] = True
request.session['customer_name'] = f"{customer.first_name} {customer.last_name}"
request.session['customer_email'] = customer.email
messages.success(request, "Logged in!!")
return redirect('index')
else:
messages.error(request, 'Incorrect password')
except customer.DoesNotExist:
messages.error(request, 'Email not found')
return render(request, 'login.html')
会话管理:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('login/', views.login_view, name='login'),
path('logout/', views.logout_view, name='logout'),
path('profile/', views.profile_view, name='profile'),
]
会话变量在
-
中设置并在
login_view
中清除。logout_view
采取的调试步骤
在不同视图中打印会话数据以确认
-
和
customer_id
设置正确。customer_name
观察到单击个人资料或注销链接总是重定向到登录页面。 - 问题
您能帮我找出为什么这些链接重定向到登录页面而不是显示个人资料或正确注销?具体来说,我需要帮助验证会话处理并确保正确的重定向。
Could you help me figure out why these links are redirecting to the login page instead of showing the profile or logging out properly? Specifically, I need assistance verifying session handling and ensuring correct redirection.
问题出在登录视图中设置会话变量的方式上。正在使用
request.session['customer_id'] = customer.id
等,但这并不安全,可能会导致 Django 错误地处理会话。
为了解决此问题,应该使用 Django 内置的
login()
函数来设置会话。
以下是修改后的代码:
views.py
from django.shortcuts import redirect, render
from django.contrib.auth import authenticate, login, logout
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .models import Customer
@login_required
def profile_view(request):
return render(request, 'profile.html')
def logout_view(request):
logout(request)
return redirect('index')
def login_view(request):
if request.method == 'POST':
email = request.POST.get('email')
password = request.POST.get('password')
try:
customer = Customer.objects.get(email=email)
if customer.check_password(password):
# 使用 Django 内置的 login 函数
login(request, customer)
messages.success(request, "Logged in!!")
return redirect('index')
else:
messages.error(request, 'Incorrect password')
except Customer.DoesNotExist:
messages.error(request, 'Email not found')
return render(request, 'login.html')
base.html
{% if user.is_authenticated %}
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
{{ user.get_full_name }}
</a>
<ul class="dropdown-menu" aria-labelledby="userDropdown">
<li><a class="dropdown-item" href="{% url 'profile' %}">Profile</a></li>
<li><a class="dropdown-item" href="{% url 'logout' %}">Logout</a></li>
</ul>
{% else %}
<a class="nav-link" href="{% url 'login' %}">Login</a>
{% endif %}
解释:
-
使用
login(request, customer)
: 我们使用 Django 的login()
函数将用户登录。这将自动设置必要的会话变量。 -
使用
user.is_authenticated
: 在模板中,我们使用user.is_authenticated
来检查用户是否已登录。 -
使用
user.get_full_name
: 使用user.get_full_name
来显示用户的全名。 -
删除不必要的会话变量:
我们不再需要手动设置
customer_id
、logged_in
、customer_name
和customer_email
等会话变量,因为 Django 会自动处理它们。
通过这些更改,的登录、注销和个人资料链接应该可以正常工作了。
标签:python,django,django-views From: 78789904