如何让非员工用户访问Django管理站点?
我想要建立一个第二个管理网站,这个网站只提供第一个管理网站的一部分功能。这是可以做到的,具体的做法在Django文档中有说明。
不过,我想限制对第一个管理网站的访问。有些用户可以访问第二个网站,但不能访问第一个网站。
为了实现这个功能,我希望这些用户不在工作人员列表中(也就是设置is_staff=False),并且重写一下AdminSite.has_permission
这个方法。
class SecondaryAdminSite(AdminSite):
def has_permission(self, request):
if request.user.is_anonymous:
try:
username = request.POST['username']
password = request.POST['password']
except KeyError:
return False
try:
user = User.objects.get(username = username)
if user.check_password(password):
return user.has_perm('app.change_onlythistable')
else:
return False
except User.DoesNotExist:
return False
else:
return request.user.has_perm('app.change_onlythistable')
可惜的是,这种方法不奏效。用户可以登录,但在第二个管理网站上什么都看不到。
这个方法有什么问题呢?有没有什么想法可以实现这个功能?
提前谢谢大家!
3 个回答
这个方法有什么问题?有没有想法如何实现这个功能?
这个方法的问题在于,权限和用户组已经可以满足你的需求。如果你只是想把用户分开,其实没必要去重新定义 AdminSite。
我觉得这可能就是为什么这个功能的文档写得这么少的原因。
这是我在使用 Django >= 3.2
时找到的解决办法。
- 首先,创建一个
AdminSite
的子类。 - 接着,重写
has_permission()
方法,去掉对is_staff
的检查。 - 然后,重写
login_form
,让它使用AuthenticationForm
。AdminSite
默认使用的是AdminAuthenticationForm
,这个类是基于AuthenticationForm
扩展的,并且增加了对is_staff
的检查。
代码
# PROJECT/APP/admin.py
from django.contrib.admin import AdminSite
from django.contrib.admin.forms import AuthenticationForm
class MyAdminSite(AdminSite):
"""
App-specific admin site implementation
"""
login_form = AuthenticationForm
site_header = 'Todomon'
def has_permission(self, request):
"""
Checks if the current user has access.
"""
return request.user.is_active
site = MyAdminSite(name='myadmin')
我觉得你现在的做法应该是可行的:http://code.djangoproject.com/ticket/14434(5周前关闭)
不过,除了使用 staff_member_required 装饰器之外,"is_staff" 的检查还是在两个地方进行的:
django.contrib.admin.forms.AdminAuthenticationForm.clean()
在 "has_permission()" 的基础上,你需要为你的非员工 AdminSite 提供一个不进行 is_staff 检查的 "login_form",所以可以通过继承并相应地调整 clean() 方法来实现。
templates/admin/base.html
这个文件需要稍微定制一下。id 为 "user-tools" 的 div 只会显示给活跃的员工。我猜这是因为登录表单也使用了这个模板,而某人可能以活跃的非员工身份登录,但仍然不应该看到那些链接。