如何让非员工用户访问 Django 管理站点?

发布于 2024-09-29 11:53:09 字数 1144 浏览 9 评论 0原文

我想实现第二个管理站点,它提供主管理站点的功能子集。这是可能的,并在 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')

不幸的是,这种方法不起作用。用户可以登录,但看不到辅助管理站点中的任何内容。

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

提前致谢

I would like to implement a 2nd admin site which provides a subset of feature of the primary admin site. That's possible and described in the Django docs

However, I would like to limit access on the primary admin site. Some users can access the 2ndary site but not the primary site.

In order to implement that feature, I would like these users not to be in the staff (is_staff=False) and rewrite the 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')

Unfortunately, this approach doesn't work. The user can login but can't see anything in the secondary admin site.

What's wrong with this approach?
Any idea how to implement this feature?

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

陪我终i 2024-10-06 11:53:09

这是对我来说 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')

Here's what worked for me with Django >= 3.2.

  • Create a subclass of AdminSite
  • Override the has_permission() method to remove the is_staff check.
  • Override the login_form to use AuthenticationForm.
    • AdminSite uses AdminAuthenticationForm, which extends AuthenticationForm and adds a check for is_staff.

Code

# 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')

墨离汐 2024-10-06 11:53:09

我认为你的方法现在应该是可能的: 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 仅针对活跃员工显示。我假设这已经完成,因为登录表单也使用此模板,并且某人可以作为活跃的非工作人员登录,但仍然不应该看到这些链接。

I think that your approach should now be possible: http://code.djangoproject.com/ticket/14434 (closed 5 weeks ago)

However, the explicit "is_staff" check is still done in two places (apart from the staff_member_required decorator):

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

    On top of "has_permission()" you'd need to provide your non-staff AdminSite with a "login_form" that doesn't do the is_staff check, so could just subclass and adjust clean() accordingly.

  • templates/admin/base.html

    would need to be slightly customized.
    The div with id "user-tools" is only shown for active staff members. I'm assuming that's done because the login form also uses this template, and someone could be logged in as an active non-staff member but still should'nt see those links.

好多鱼好多余 2024-10-06 11:53:09

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

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

恕我直言,这可能就是这个功能的记录如此之少的原因

What's wrong with this approach? Any idea how to implement this feature?

What's wrong with this approach is that permissions and groups can already provide you with what you need. There is no need to subclass AdminSite if all you need is to divide users.

This is probably why this feature is so poorly documented, IMHO

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文