如何使编外用户访问 Django 管理站点?

Posted

技术标签:

【中文标题】如何使编外用户访问 Django 管理站点?【英文标题】:How to make Django admin site accessed by non-staff user? 【发布时间】:2011-04-30 16:03:38 【问题描述】:

我想实现第二个管理站点,它提供主管理站点的一部分功能。这是可能的,并在Django docs

中进行了描述

但是,我想限制对主管理站点的访问。有些用户可以访问第二个站点,但不能访问主站点。

为了实现该功能,我希望这些用户不要在人员中(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')

很遗憾,这种方法行不通。用户可以登录,但在辅助管理站点中看不到任何内容。

这种方法有什么问题? 知道如何实现此功能吗?

提前致谢

【问题讨论】:

你为什么不把你的用户划分成超级用户、经理、客户等等——权限系统工作得很好。 @Tomasz:我也在这样做。第二个管理站点具有不同的目的,因此可以针对不同类型的用户。我想避免他们连接到通常的管理员。 我假设您正在验证是否正在调用正确的has_permission?页面上没有任何显示(即完全空白),还是只是隐藏了管理功能? 它说我对这个应用没有任何权利。如果我恢复登录用户的 is_staff,我可以看到模型。 is_staff 是管理员要求的。如果您出于某种原因无法将这些用户设置为 true,我认为您最好的选择是编写自己的管理视图。使用像 has_permission 装饰器这样的访问控制,您可以实施自己的授权方案。 【参考方案1】:

Django >= 3.2 对我有用。

创建AdminSite的子类 重写has_permission() 方法以删除is_staff 检查。 覆盖login_form 以使用AuthenticationFormAdminSite 使用 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')

【讨论】:

【参考方案2】:

我认为您的方法现在应该可行:http://code.djangoproject.com/ticket/14434(5 周前关闭)

但是,显式的“is_staff”检查仍然在两个地方进行(除了 staff_member_required 装饰器):

django.contrib.admin.forms.AdminAuthenticationForm.clean()

在“has_permission()”之上,您需要为您的编外人员 AdminSite 提供一个不进行 is_staff 检查的“login_form”,因此可以子类化并相应地调整 clean()。

模板/admin/base.html

需要稍微定制。 id 为“user-tools”的 div 仅显示给在职员工。我假设已经完成,因为登录表单也使用此模板,并且有人可以作为活跃的编外人员登录,但仍然不应该看到这些链接。

【讨论】:

感谢您提供此信息,我会试一试 请告诉我你的进展,因为它未经测试,我想在某个阶段做同样的事情:-) 如果这就是您需要更改的全部内容,请也回复票证。对于额外的布朗尼积分,您甚至可以在那里处理补丁,每个人都会受益! :) 我认为我对 AdminSite 的了解不足以创建补丁 :-)... 棘手,棘手 - AdminSite.login_form 是一个 AdminAuthenticationForm 但后者还没有属性另一个方向并询问 has_permission() 的“它的”AdminSite(多个可以共享相同的 login_form ...)...这可以传递给构造函数,但我不知道后果 - 用请求实例化( cookies) 和所有...模板有同样的问题。根据具体情况,我可以将一段硬编码的代码与另一段交换,通用解决方案更难......【参考方案3】:

这种方法有什么问题?知道如何实现此功能吗?

这种方法的问题在于权限和组已经可以为您提供所需的内容。如果您只需要划分用户,则无需子类化 AdminSite。

这可能就是为什么这个功能的文档记录如此糟糕,恕我直言

【讨论】:

第二个站点不仅是管理权限的不同方式。它提供自定义屏幕和附加功能。 django 管理站点很棒,可以高度定制。 Stange 有点难以定制

以上是关于如何使编外用户访问 Django 管理站点?的主要内容,如果未能解决你的问题,请参考以下文章

Django 管理站点:添加用户页面如何工作(编辑更多字段)?

Django 中Admin站点的配置

Django站点管理

Django的Admin站点管理

如何使某个模板仅对 Django 中已确认的用户可见?

Django 管理站点,更改不同用户的模型可见性