gpt4 book ai didi

python - 了解 Django 3.1 中的模型权限

转载 作者:行者123 更新时间:2023-12-05 06:08:59 27 4
gpt4 key购买 nike

我很难理解 Django 3.1 如何检查权限,尤其是模型权限与默认权限的处理方式。

我有以下模型:

from django.db import models
class MyModel(models.Model):
class Meta:
permissions = [("finalize", "Can finalize"),]
is_final = models.BooleanField(default = False)

它为此模型定义了一个新的 finalize 权限。随着模型的出现,我们有一个模型管理员:

from django.contrib import admin
from django.contrib.auth import get_permission_codename
from .models import *

class MyModelAdmin(admin.ModelAdmin):
actions = ['set_final', 'remove_final']

def set_final(self, request, queryset):
queryset.update(is_final=True)
set_final.allowed_permissions = ('finalize',)

def remove_final(self, request, queryset):
queryset.update(is_final=False)
remove_final.allowed_permissions = ('finalize',)

# Permissions

def has_change_permission(self, request, obj = None):
if obj and obj.is_final:
return False
codename = get_permission_codename('change', self.opts)
print("has_perm(change) : %s.%s : %s" % (self.opts.app_label, 'change', request.user.has_perm('%s.%s' % (self.opts.app_label, 'change'))))
print("has_perm(codename): %s.%s : %s" % (self.opts.app_label, codename, request.user.has_perm('%s.%s' % (self.opts.app_label, codename))))
return request.user.has_perm('%s.%s' % (self.opts.app_label, codename))

def has_finalize_permission(self, request, obj = None):
codename = get_permission_codename('finalize', self.opts)
print("has_perm(finalize): %s.%s : %s" % (self.opts.app_label, 'finalize', request.user.has_perm('%s.%s' % (self.opts.app_label, 'finalize'))))
print("has_perm(codename): %s.%s : %s" % (self.opts.app_label, codename, request.user.has_perm('%s.%s' % (self.opts.app_label, codename))))
return request.user.has_perm('%s.%s' % (self.opts.app_label, 'finalize'))

admin.site.register(MyModel, MyModelAdmin)

它定义了两个 Action :设置和移除对象的 is_final 标志。与它一起,has_change_permission 被重新定义,因为对象应该显示为“view”——只有当 is_final 标志被设置时。

现在我创建一个新的员工级别用户,它通过 Django 管理界面接收模型的所有权限(查看、添加、更改、完成)。难题来了。使用该用户登录时,上述 print 语句的计算结果如下:

has_perm(finalize): myapp.finalize : True
has_perm(codename): myapp.finalize_mymodel : False
has_perm(change) : myapp.change : False
has_perm(codename): myapp.change_mymodel : True

(请记住,用户已收到从用户管理界面列表中选择的模型的所有权限)。所以不知何故

  • 使用 get_permission_codename() 的值调用模型定义的权限计算结果为 false
  • 使用直接名称 myapp.change 调用默认权限的结果为 false

有人可以向我解释为什么会出现这种行为以及如何正确实现权限检查吗?

最佳答案

我不知道这是否是 Django 3.1 中的错误。您正在遵循文档中的建议。但是 Django contrib.auth get_permission_codename() 以 app.permission_modelname 的形式返回权限。当您设置允许的权限“finalize”时,它会作为 app.finalize 添加到 Permission 模型中。但是当您使用 get_permission_codename() 时,它会返回一个字符串作为 app.finalize_mymodel。当authenticator backend比较两者时,显然不匹配,返回False。“更改”权限是不同的——内置于 Django 中(所有管理 View 默认添加、更改、删​​除权限),它按照 Django 的要求进行设置。只有用户提供(对于非 super 用户)才会遇到此问题。我通过不使用 get_permission_codename() 解决了这个问题。相反,只需将 opts.app_label 和您的权限 str 传递给 request.user.has_perm()。同样 - 我不知道这在未来的版本中是否有所改变。

关于python - 了解 Django 3.1 中的模型权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64984409/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com