如何在Django中限制URL仅对管理员及员工用户开放
限制Django URL仅对管理员/员工开放的方案
当然有办法实现这个需求!针对你已经用login_required限制登录用户的场景,这里有几种更精准的方案,能让URL仅对管理员(is_superuser)或员工(is_staff)开放,排除普通登录用户:
1. 直接用user_passes_test装饰器(快速适配现有代码)
Django自带的user_passes_test装饰器支持自定义用户校验逻辑,比login_required更灵活。你可以直接在urls.py里替换原来的login_required:
首先定义一个校验函数,检查用户是否是管理员或员工:
from django.contrib.auth.decorators import user_passes_test def is_admin_or_staff(user): # 先确保用户已登录,再检查是否是管理员/员工 return user.is_authenticated and (user.is_superuser or user.is_staff)
然后在urlpatterns里使用这个装饰器包装你的类视图:
urlpatterns = [ url(r'^$', user_passes_test(is_admin_or_staff)(views.MainView.as_view()), name='index') ]
如果是函数视图,直接用装饰器标记即可:
@user_passes_test(is_admin_or_staff) def my_function_view(request): # 你的视图逻辑 pass
2. 自定义复用装饰器(适合多视图场景)
如果多个视图都需要这个权限校验,可以把逻辑封装成自定义装饰器,用起来和login_required一样方便:
from django.contrib.auth.decorators import user_passes_test def admin_or_staff_required(view_func): # 用lambda简化校验逻辑 return user_passes_test( lambda user: user.is_authenticated and (user.is_superuser or user.is_staff) )(view_func)
使用示例:
# 函数视图 @admin_or_staff_required def my_view(request): pass # urls.py中的类视图 urlpatterns = [ url(r'^$', admin_or_staff_required(views.MainView.as_view()), name='index') ]
3. 类视图Mixin(符合Django类视图风格)
如果你更习惯用类视图的继承方式,可以自定义一个权限Mixin,让类视图直接继承即可:
from django.contrib.auth.mixins import AccessMixin from django.http import HttpResponseForbidden class AdminOrStaffRequiredMixin(AccessMixin): def dispatch(self, request, *args, **kwargs): # 先检查是否登录 if not request.user.is_authenticated: return self.handle_no_permission() # 再检查是否是管理员/员工 if not (request.user.is_superuser or request.user.is_staff): return HttpResponseForbidden("你没有权限访问此页面") return super().dispatch(request, *args, **kwargs)
然后修改你的类视图,继承这个Mixin:
from django.views.generic import View class MainView(AdminOrStaffRequiredMixin, View): def get(self, request): # 你的视图逻辑 pass
这时候urls.py就不用加装饰器了,直接写:
urlpatterns = [ url(r'^$', views.MainView.as_view(), name='index') ]
小提示
- 以上方案都包含了用户登录状态的检查,避免未登录用户直接访问
- 如果需要自定义无权限时的跳转(比如跳转到403页面),可以在
user_passes_test里添加login_url或redirect_field_name参数,或者在Mixin里自定义响应内容
内容的提问来源于stack exchange,提问作者Jay P.
相关产品推荐
相关产品推荐

