Django登录验证通过后无法重定向至首页或Admin面板问题
Django登录验证通过后无法重定向的问题
执行python manage.py runserver 0.0.0.0:8000启动服务后,访问Admin登录页始终停留在http://192.168.0.81:8000/admin/login/?next=/admin/,用户名与密码验证通过后无法跳转到首页(index)或Admin仪表盘。
相关代码片段
views.py
from django.shortcuts import redirect from django.contrib.auth import authenticate, login from django.contrib.auth.models import User from django.contrib import messages from auth.views import AuthView class LoginView(AuthView): def get(self, request): if request.user.is_authenticated: # 如果用户已登录,重定向到首页或其他合适页面 return redirect("index") # 替换为首页实际的URL名称 # 为未登录用户渲染登录页 return super().get(request) def post(self, request): if request.method == "POST": username = request.POST.get("email-username") password = request.POST.get("password") if not (username and password): messages.error(request, "请输入用户名和密码。") return redirect("login") if "@" in username: user_email = User.objects.filter(email=username).first() if user_email is None: messages.error(request, "请输入有效的邮箱。") return redirect("login") username = user_email.username user_email = User.objects.filter(username=username).first() if user_email is None: messages.error(request, "请输入有效的用户名。") return redirect("login") authenticated_user = authenticate(request, username=username, password=password) if authenticated_user is not None: # 验证成功则登录用户 login(request, authenticated_user) # 重定向到用户登录前尝试访问的页面 if "next" in request.POST: return redirect(request.POST["next"]) else: # 否则重定向到首页或其他合适页面 return redirect("index") else: messages.error(request, "请输入有效的用户名。") return redirect("login")
settings.py
""" Django settings for web_project project. Generated by 'django-admin startproject' using Django 4.2.1. For more information on this file, see https://docs.djangoproject.com/en/4.2/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/4.2/ref/settings/ """ import os from pathlib import Path from django.utils.translation import gettext_lazy as _ from dotenv import load_dotenv from .template import TEMPLATE_CONFIG, THEME_LAYOUT_DIR, THEME_VARIABLES load_dotenv() # 从.env文件加载环境变量 # 项目内路径构建方式:BASE_DIR / '子目录' BASE_DIR = Path(__file__).resolve().parent.parent # 快速开发设置 - 不适合生产环境 # 参见 https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ # 安全警告:生产环境中要保密secret key! SECRET_KEY = os.environ.get("SECRET_KEY", default='') # 安全警告:生产环境不要开启debug模式! DEBUG = os.environ.get("DEBUG", 'True').lower() in ['true', 'yes', '1'] # https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts ALLOWED_HOSTS = ["192.168.0.81","localhost", "0.0.0.0", "127.0.0.1"] # 当前Django环境 ENVIRONMENT = os.environ.get("DJANGO_ENVIRONMENT", default="local") # 应用定义 INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "apps.dashboards", "auth.apps.AuthConfig" ] MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "whitenoise.middleware.WhiteNoiseMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.locale.LocaleMiddleware", "web_project.language_middleware.DefaultLanguageMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", ] ROOT_URLCONF = "config.urls" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [BASE_DIR / "templates"], "APP_DIRS": True, "OPTIONS": { "context_processors": [ "django.template.context_processors.debug", "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", "config.context_processors.language_code", "config.context_processors.my_setting", "config.context_processors.get_cookie", "config.context_processors.environment", ], "libraries": { "theme": "web_project.template_tags.theme", }, "builtins": [ "django.templatetags.static", "web_project.template_tags.theme", ], }, }, ] WSGI_APPLICATION = "config.wsgi.application" # 数据库 # https://docs.djangoproject.com/en/4.2/ref/settings/#databases DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", "NAME": BASE_DIR / "db.sqlite3", } } # 密码验证 # https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", }, { "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", }, { "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", }, ] # 国际化 # https://docs.djangoproject.com/en/4.2/topics/i18n/ # 启用国际化并设置支持的语言列表 LANGUAGES = [ ("en", _("English")), ("fr", _("French")), ("ar", _("Arabic")), ("de", _("German")), # 根据需要添加更多语言 ] # 设置默认语言 # ! 修改默认语言后请清除浏览器缓存 LANGUAGE_CODE = "en" TIME_ZONE = "UTC" USE_I18N = True USE_L10N = False USE_TZ = True LOCALE_PATHS = [ BASE_DIR / "locale", ] # 静态文件(CSS、JavaScript、图片) # https://docs.djangoproject.com/en/4.2/howto/static-files/ STATIC_URL = "/static/" STATIC_ROOT = BASE_DIR / "staticfiles" STATICFILES_DIRS = [ BASE_DIR / "src" / "assets", ] # 特定环境下Django应用运行的默认URL BASE_URL = os.environ.get("BASE_URL", default="http://192.168.0.81:8000") # if not DEBUG: # STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' # 默认主键字段类型 # https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" # 模板设置 # ------------------------------------------------------------------------------ THEME_LAYOUT_DIR = THEME_LAYOUT_DIR TEMPLATE_CONFIG = TEMPLATE_CONFIG THEME_VARIABLES = THEME_VARIABLES # 邮件设置 # ------------------------------------------------------------------------------ EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" EMAIL_HOST = "smtp.gmail.com" EMAIL_PORT = 587 EMAIL_USE_TLS = True EMAIL_HOST_USER = "" EMAIL_HOST_PASSWORD = "" # 登录相关设置 # ------------------------------------------------------------------------------ LOGIN_URL = "/login/" LOGOUT_REDIRECT_URL = "/login/" # 会话设置 # ------------------------------------------------------------------------------ SESSION_ENGINE = "django.contrib.sessions.backends.db" SESSION_COOKIE_SECURE = True SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_SAMESITE = None SESSION_COOKIE_AGE = 3600 CSRF_TRUSTED_ORIGINS = [ "http://192.168.0.81:8000", "http://0.0.0.0:8000", "http://localhost:5050", ]
问题排查与解决方案
1. 修复next参数获取逻辑
Admin登录页的next参数是放在URL查询字符串(request.GET)中的,而你的代码只从request.POST中读取该参数,导致验证成功后无法跳转到Admin仪表盘。修改LoginView的post方法:
# 替换原有的next判断部分 next_url = request.POST.get("next") or request.GET.get("next") if next_url: return redirect(next_url) else: return redirect("index")
2. 调整会话安全设置
当前SESSION_COOKIE_SECURE = True,但你使用HTTP协议访问服务,浏览器会拒绝保存会话Cookie,导致登录状态无法维持。开发环境下建议关闭该设置:
# 在settings.py中修改 SESSION_COOKIE_SECURE = False # 生产环境再改为True
3. 确认index路由名称正确性
检查项目的URL配置,确保存在名称为index的路由,例如:
# config/urls.py from django.urls import path from apps.dashboards.views import IndexView urlpatterns = [ path('', IndexView.as_view(), name='index'), # 其他路由配置... ]
4. 验证中间件顺序
确保AuthenticationMiddleware在SessionMiddleware之后,当前你的中间件顺序是正确的,若后续调整需注意保持该顺序,否则会话无法被正确识别。
内容的提问来源于stack exchange,提问作者iwan hermawan
相关产品推荐
相关产品推荐

