Django自定义Admin视图添加身份验证报错:'QuestionAdmin'无user属性
解决Django Admin自定义视图添加staff验证报错问题
错误原因
直接给ModelAdmin的实例方法加staff_member_required装饰器会导致参数传递异常——这个装饰器是为独立视图函数设计的,而ModelAdmin的自定义方法是绑定到实例的,调用时装饰器会错误地把self当成请求对象,进而找不到user属性。
解决方案:用Admin内置的admin_view包装视图
Django Admin提供了admin_view()方法,专门用来处理Admin内部自定义视图的权限验证(包括staff用户检查)和CSRF保护,比单独用staff_member_required更适配Admin上下文。
修改代码如下:
from django.contrib import admin from django.urls import path from django.shortcuts import render, redirect from .models import Question class QuestionAdmin(admin.ModelAdmin): list_display = ('question_text', 'pub_date') def get_urls(self): urls = super().get_urls() # 用admin_site.admin_view包装自定义视图 new_urls = [ path('upload-csv/', self.admin_site.admin_view(self.upload_csv)), ] return new_urls + urls def upload_csv(self, request): return render(request, "admin/csv_upload.html") admin.site.register(Question, QuestionAdmin)
备选方案:用method_decorator适配装饰器
如果你坚持使用staff_member_required,可以用Django的method_decorator将函数装饰器转换为适用于实例方法的装饰器:
from django.contrib import admin from django.urls import path from django.shortcuts import render, redirect from .models import Question from django.contrib.admin.views.decorators import staff_member_required from django.utils.decorators import method_decorator class QuestionAdmin(admin.ModelAdmin): list_display = ('question_text', 'pub_date') def get_urls(self): urls = super().get_urls() new_urls = [ path('upload-csv/', self.upload_csv), ] return new_urls + urls @method_decorator(staff_member_required) def upload_csv(self, request): return render(request, "admin/csv_upload.html") admin.site.register(Question, QuestionAdmin)
说明
第一种方案更推荐,因为admin_view()不仅会验证staff身份,还会自动处理Admin视图所需的CSRF保护、登录重定向等逻辑,完全贴合Admin的运行环境。
内容的提问来源于stack exchange,提问作者Mirzonabot Mirzonabotov
相关产品推荐
相关产品推荐

