我正准备使用django-guardian,直到我在官方文档中遇到以下内容:
权限不仅可以针对每种类型的对象进行设置,还可以针对特定对象实例进行设置.通过使用ModelAdmin类提供的has_add_permission(),has_change_permission()和has_delete_permission()方法,可以为同一类型的不同对象实例自定义权限.
这是否意味着更新版本的Django不再需要django-guardian?
请澄清.
迁移我的django和userena包后,如下所示
Django 1.8到Django 1.9.7
django-userena 1.4.1到django-userena == 2.0.1
运行项目后,我遇到了这个错误
Unhandled exception in thread started by <function wrapper at 0xb689641c>
Traceback (most recent call last):
File "/home/Documents/environments/venv/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 226, in wrapper
fn(*args, **kwargs)
File "/home/Documents/environments/venv/local/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 116, in inner_run
self.check(display_num_errors=True)
File "/home/Documents/environments/venv/local/lib/python2.7/site-packages/django/core/management/base.py", line 426, in check
include_deployment_checks=include_deployment_checks,
File "/home/Documents/environments/venv/local/lib/python2.7/site-packages/django/core/checks/registry.py", line 75, in run_checks
new_errors = check(app_configs=app_configs)
File "/home/Documents/environments/venv/local/lib/python2.7/site-packages/django/core/checks/urls.py", line 13, in check_url_config
return check_resolver(resolver)
File "/home/Documents/environments/venv/local/lib/python2.7/site-packages/django/core/checks/urls.py", line 23, in check_resolver
for pattern in resolver.url_patterns:
File "/home/Documents/environments/venv/local/lib/python2.7/site-packages/django/utils/functional.py", line 33, in __get__
res …Run Code Online (Sandbox Code Playgroud) 我目前正在创建一个我拥有属于公司的员工的结构.在这家公司内,我需要能够创建几个组.排名如果你愿意.您可以为较低级别分配较少的权限,为较高级别分配较多权限.
我想去对象级权限,我注意到django-guardian项目给了我正确的我需要的东西.它适用于本机用户和组对象,因此我现在正在尝试找到一种在公司对象中实现本机组对象的方法.
我面临的问题是组中的名称是唯一的.因此,如果2家公司添加相同的组,则会发生错误.
我找到了一种在某种程度上有效的实现,但对我来说似乎相当'hacky'.在我的公司,我声明了一个引用Group的组变量:
class Company(models.Model):
...
groups = models.ManyToManyField(Group, through='CompanyRole')
Run Code Online (Sandbox Code Playgroud)
CompanyRole基本上包含组名和对公司和组的引用
class CompanyRole(models.Model):
group = models.ForeignKey(Group)
company = models.ForeignKey(Company)
real_name = models.CharField(max_length=60, verbose_name=_('Real name'))
objects = CompanyGroupManager()
Run Code Online (Sandbox Code Playgroud)
我用一种方便的方法创建了一个自定义管理器来添加一个新的"公司组"
class CompanyGroupManager(models.Manager):
def create_group(self, company, group_name):
un_group_name = str(company.id) + '#' + group_name
group = Group.objects.create(name=un_group_name)
company_group = self.model(
real_name=group_name,
company=company,
group=group
)
company_group.save(using=self._db)
return company_group
Run Code Online (Sandbox Code Playgroud)
这是我真的觉得不舒服的部分.为了使用Group模型上的唯一名称更改问题,我使用了公司ID,哈希符号和实际组名称的组合来避免冲突.
现在我的问题是:在我的场景中是否有更好的方法,我错过了什么或者这是完成我需要的好方法吗?
我在Django中为一个非常复杂的系统建模.我将在这里仅发布它的相关部分,我将展示简化的用例图表,以更好地表达我的想法.
我基本上有两种类型的用户:卖家和客户.
一个卖家 " 获得 "一个客户,是指卖方现在有客户的个人信息,并可以与他/她交互.
卖方不能与他未获得的客户互动.

一个卖家创建模型的层次结构相关的对象(在分段每个模型与外键,其父连)

一个卖家 共享创建的框对象及其所有相关对象与一些客户

授权客户可以:

问题:
django django-models django-permissions django-users django-guardian
我正在实现一个API,我有嵌套结构.让我们说它是一个动物园,我可以打电话GET /api/cage/来获得一个笼子列表GET /api/cage/1/来获得笼子ID 1,但是我可以GET /api/cage/1/animals/得到一个笼子中的动物列表.我遇到的问题是权限.如果我能看到笼子本身,我应该只能看到笼子里的动物.如果has_object_permission()在相关的权限类中返回True,我应该能够看到笼子本身.出于某种原因,当我执行GET/api/cage/1 /时会调用has_object_permission(),但是当我调用时会调用has_permission()GET /api/cage/1/animals/.使用has_permission(),我无权访问该对象来检查权限.我错过了什么吗?我该怎么做呢?
我的笼子视图看起来或多或少像这样
class CageViewSet(ModelViewSet):
queryset = Cage.objects.all()
serializer_class = CageSerializer
permission_classes = [GeneralZooPermissions, ]
authentication_classes = [ZooTicketCheck, ]
def get_queryset(self):
... code to only list cages you have permission to see ...
@detail_route(methods=['GET'])
def animals(self, request, pk=None):
return Request(AnimalSerializer(Animal.objects.filter(cage_id=pk), many=True).data)
我的GeneralZooPermissions类看起来像这样(目前)
class GeneralZooPermissions(BasePermission):
def has_permission(self, request, view):
return True
def has_object_permission(self, request, view, obj):
return request.user.has_perm('view_cage', obj)
更新#1:看起来这是DRF中的一个错误.详细信息路由不会调用正确的权限检查.我曾尝试向DRF开发者报告此问题,但我的报告似乎已经消失.不知道下一步该怎么做.想法?
更新#2:我在DRF上发布的问题又回来了,我收到了回复.似乎只检查has_permission()而不是has_object_permission()是预期的行为.对我没有帮助,所以我仍在寻找解决方案.在这一点上,必须要做这样的事情
class CustomPermission(BasePermission):
def has_permission(self, request, view):
"""we … 我正在使用django-guardian来管理每个对象的权限.
对于给定的用户,我授予对一个对象的所有权限:
joe = User.objects.get(username="joe")
mytask = Task.objects.get(pk=1)
assign('add_task', joe, mytask)
assign('change_task', joe, mytask)
assign('delete_task', joe, mytask)
Run Code Online (Sandbox Code Playgroud)
我按预期得到了:
In [57]: joe.has_perm("add_task", mytask)
Out[57]: True
In [58]: joe.has_perm("change_task", mytask)
Out[58]: True
In [59]: joe.has_perm("delete_task", mytask)
Out[59]: True
Run Code Online (Sandbox Code Playgroud)
在admin.py中我也使TaskAdmin继承GuardedModelAdmin而不是admin.ModelAdmin
现在当我用joe连接到我的网站时,我得到了管理员:
You don't have permission to edit anything
Run Code Online (Sandbox Code Playgroud)
我不应该能够编辑对象mytask吗?
我是否必须使用内置的基于模型的权限系统设置一些权限?
我错过了什么吗?
编辑
我试图添加选项user_can_access_owned_objects_only,这应该是我的问题,但我仍然看不到我的管理员...
class TaskAdmin(GuardedModelAdmin):
user_can_access_owned_objects_only = True
pass
admin.site.register(Task, TaskAdmin)
Run Code Online (Sandbox Code Playgroud)
谢谢
django permissions django-admin django-authentication django-guardian
有
from guardian.shortcuts import get_objects_for_user
Run Code Online (Sandbox Code Playgroud)
但是关于
from guardian.shortcuts import get_users_for_object
Run Code Online (Sandbox Code Playgroud)
谢谢。
我已将django-guardian的行级权限添加到我的项目中.
从设置看起来一切正常:
但是,分配(分配不分配)权限对管理界面完全没有影响.允许每个用户对所有对象执行所有操作.
我试过了
user_can_access_owned_objects_only = True
Run Code Online (Sandbox Code Playgroud)
但这只会影响查看对象的能力.一旦用户看到它,他也可以更改并删除它.无论权限中设置了什么.
我跟随另一个在ModelAdmin中提出这个问题的讨论
def queryset(self, request):
if request.user.is_superuser:
return get_objects_for_user(user=request.user, perms=['change_program'], klass=Program)
Run Code Online (Sandbox Code Playgroud)
但是这具有与上面类似的效果,它仅限制可见项目.
我希望看到管理员"保存"和"删除"按钮(和功能)听django-guardian.这是误会吗?或者我不是走在整条路上了吗?
谢谢你的提示![R
我正在使用带有嵌套路由器扩展的Django REST框架.我的一条路线看起来像:companies/$company/locations/$location其中$company和$location是slug变量.
我想允许用户POST到此URL:companies/$company/locations/添加新位置.我想确保执行POST的用户具有他正在POST的公司的更正权限.我目前django-guardian用于我的对象级权限.POST消息仅包含新位置的名称,它不包含公司名称,因为可以从URL中推断出该名称.在这种情况下,我很难正确地执行权限.我一直在从viewset的方法设置company新Location对象的字段,pre_save但这对于应用权限检查来说太迟了.
执行此操作的最佳方法是什么?
如果用户确实在POST中包含公司,我可以通过在视图集中添加以下内容来验证公司:
def get_queryset(self):
parent = super(LocationViewSet, self).get_queryset()
return parent.filter(company__slug=self.kwargs['company_slug'])
Run Code Online (Sandbox Code Playgroud) 为什么 django rest 框架在创建对象时不检查对象权限?用户应该能够创建他们无法看到、更新或删除的对象是没有意义的(无论如何对我来说)。目前我子类化了一个视图集
class CheckCreatePermissionsViewSet(ModelViewSet):
def perform_create(self, serializer):
'''
Called by create before calling serializer.save()
'''
obj = serializer.save()
try:
self.check_object_permissions(obj)
except:
obj.delete()
raise
Run Code Online (Sandbox Code Playgroud)
为什么默认情况下不实现?这让我很头疼,我想不出它会像这样实施的单一原因。