Django中@login_required函数报错:找不到registration/login.html模板
问题描述
使用Django的@login_required装饰器时出现错误:
TemplateDoesNotExist at /accounts/login/
registration/login.html
我的模板都存放在根目录的templates文件夹中,login.html模板在直接访问登录页面时可正常使用,未创建registration子目录。
相关代码
带@login_required的视图代码
@login_required(login_url='signin') def buy_crypto(request): if request.method == 'POST': currency = request.POST.get('currency') amount = Decimal(request.POST.get('amount')) price_per_unit = Decimal(request.POST.get('price_per_unit')) purchase = CryptoPurchase(user=request.user, currency=currency, amount=amount, price_per_unit=price_per_unit) purchase.save() return redirect('index') else: return render(request, 'buy_crypto.html')
accounts应用的urls.py
from django.urls import path from cryptoapp import views from .views import signupView, signinView, signoutView urlpatterns = [ path('create/', signupView, name='signup'), path('login/', signinView, name='signin'), path('signout/', signoutView, name='signout'), ]
项目settings.py关键配置
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR / 'templates'], 'APP_DIRS': True, # ...其他上下文处理器配置 }, ] AUTH_USER_MODEL = 'accounts.CustomUser' LOGIN_REDIRECT_URL = "/"
解决方案
核心原因
未登录用户访问buy_crypto视图时,@login_required会跳转到signin对应的URL(/accounts/login/),但处理该请求的signinView可能依赖了Django内置登录视图的默认模板路径(registration/login.html),而非你自定义的templates/login.html。
解决步骤
修正
signinView的模板渲染逻辑
确保自定义登录视图明确指定渲染templates/login.html,示例代码:# accounts/views.py from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login def signinView(request): if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) return redirect('index') else: return render(request, 'login.html', {'error': '无效的账号或密码'}) else: return render(request, 'login.html')全局配置登录URL(可选优化)
在settings.py中添加全局登录URL配置,这样所有@login_required装饰器默认跳转到你的登录页面,无需逐个指定login_url:LOGIN_URL = 'signin'之后视图中的装饰器可简化为:
@login_required def buy_crypto(request): # ...原有视图逻辑确认模板加载路径有效性
当前settings.py中已将根目录templates添加到TEMPLATES的DIRS中,Django会优先从该目录加载模板,此配置无需修改。
内容的提问来源于stack exchange,提问作者thedublinbloke
相关产品推荐
相关产品推荐

