Django-guardian: 仅为特定组添加/删除成员

创建于 2017-11-20  ·  35评论  ·  资料来源: django-guardian/django-guardian

嗨,我需要一个权限,让特定组的用户只能为所属组添加、删除或删除。

所有35条评论

没问题,您必须创建此类权限并使用 django-guardian 支持手动实施访问控制。

访问控制之类的?

如何实现此功能?

Django-guardian 是一个适用于任何对象的访问控制库。 这样的对象也可以是组。 请参阅示例项目中的访问控制。 请参阅https://github.com/django-guardian/django-guardian/blob/devel/example_project/articles/views.py#L35

完美的!

这是我的片段代码:

def create_user_profile(sender, instance, created, **kwargs):
    print("create_user_profile")
    try:
        print("created: "+ str(created))
        if created:
            Profile.objects.create(user=instance)
            print("Member.objects.get_or_create(django_user=instance)")
            #Create a user into groups_manager_member
            member = Member.objects.create(django_user=instance, first_name=instance.first_name, last_name=instance.last_name, username=instance.username, email=instance.email)
            print("member instance created")
            print(member)
            print("Group.objects.create(name=ID_GROUP+instance.username)")

            #Create a group into groups_manager_group
            group = Group.objects.create(name=ID_GROUP+instance.username)
            print("group instance created")
            print(group)
            #Add member into the group correct
            group.add_member(member=member)
            print("member added into the group correct")

    except Exception as e:
        print("Exception: "+str(e))
        pass


def save_user_profile(sender, instance, **kwargs):
    print("save_user_profile")
    try:
        instance.profile.save()

    except Exception as e:
        print("Exception: "+str(e))
        pass

post_save.connect(create_user_profile, sender=User)
post_save.connect(save_user_profile, sender=User)

我需要拥有为该组的所有用户添加/删除的权限。

不知道你哪里有问题。 你需要这样的东西:

class ProtectedGroupUpdateView(PermissionRequiredMixin, GroupUpdateView):
    permission_required = ['change_group', ]
    ...

并在创建时为组分配权限。

我尝试添加“可以添加成员”的权限,但是所有组都可以,而不是员工。

我不知道你是什么意思。 django-guardian 权限总是授予用户或用户组。 无法根据角色或特殊条件授予权限。 如果要授予员工管理“X”组的权限,请创建“员工”组,向其中添加员工,添加“X”组,并授予“员工”组管理“X”的权限团体。

我需要一个属于一个组的用户
“X”只能为“X”组添加或删除,不幸的是,如果您拥有“您可以添加用户”的权限,则可以为所有组而不是学徒组执行此操作。

对不起,我的英语不好

不幸的是,我无法理解您的期望。 仔细检查示例项目。 在这种情况下,这应该就足够了。

"X" can add or remove only for group "X"表示:

  1. 创建组 X,
  2. 添加X组成员
  3. 分配 X 组权限以管理 X 组。

我实际上需要确保属于“x”组的用户只能在他自己的组中添加或删除其他用户

@Allan-Nava django-guardian 权限始终授予用户或用户组。 无法根据角色或特殊条件授予权限。 如果您希望用户管理他们的组,请授予组权限以将该组作为对象进行管理。

您是否了解如何分配和检查“X”组权限以管理“X”组?

它应该像netflix(但所有成员都可以登录):每个用户都应该有一个个人组,他可以根据自己的喜好添加或删除用户。 问题是,如果您授予此权限添加用户,这会影响所有其他组,而不是属于该组的用户

问题是,如果您授予此权限添加用户,这会影响所有其他组,而不是属于该组的用户

这绝对不是真的。 这句话对于Django核心来说是正确的。 如果您使用正确的 Django-guardian 权限授予管理组 X 的 X 组仅适用于 X 组。 就像在示例项目中一样,授予管理特定文章的权限并不意味着可以编辑其他文章由该用户。

我想创建一个权限,允许所有用户将其他人添加到他们的成员资格组。 每次我创建一个新用户时,他的成员身份组为“X”,我都希望创建一个名为“可以为 X 添加组”的新权限,并且该权限必须将组“X”作为对象。

像这样:

def create_user_profile(sender, instance, created, **kwargs):
    print("create_user_profile")
    try:
        print("created: "+ str(created))
        if created:
            Profile.objects.create(user=instance)
            print("Member.objects.get_or_create(django_user=instance)")
            #Create a user into groups_manager_member
            member = Member.objects.create(django_user=instance, first_name=instance.first_name, last_name=instance.last_name, username=instance.username, email=instance.email)
            print("member instance created")
            print(member)
            print("Group.objects.create(name=ID_GROUP+instance.username)")

            #Create a group into groups_manager_group
            group = Group.objects.create(name=ID_GROUP+instance.username)
            print("group instance created")
            print(group)
            #Add member into the group correct
            group.add_member(member=member)
            print("member added into the group correct")
            UserObjectPermission.objects.assign_perm('can_add_member_for_xgroup', member, obj=group)

    except Exception as e:
        print("Exception: "+str(e))
        pass


def save_user_profile(sender, instance, **kwargs):
    print("save_user_profile")
    try:
        instance.profile.save()

    except Exception as e:
        print("Exception: "+str(e))
        pass

post_save.connect(create_user_profile, sender=User)
post_save.connect(save_user_profile, sender=User)



异常是创建一千个权限。 assign_perm('manage_group',group,group)assign_perm('manage_group',user,group)应该足够了。 剩下的就是验证用户是否具有管理特定组的权限。

好的,完美,但在 templare 视图中,我如何检查?

{{ perms.groups_manager.canaddmemberx2}}

@Allan-Nava 再次仔细检查示例项目,尤其是模板RTFD

@ad-m 好的,谢谢,所以我的代码片段:

from guardian.shortcuts import assign_perm

def create_user_profile(sender, instance, created, **kwargs):
    print("create_user_profile")
    try:
        print("created: "+ str(created))
        if created:
            Profile.objects.create(user=instance)
            print("Member.objects.get_or_create(django_user=instance)")
            #Create a user into groups_manager_member
            member = Member.objects.create(django_user=instance, first_name=instance.first_name, last_name=instance.last_name, username=instance.username, email=instance.email)
            print("member instance created")
            print(member)
            print("Group.objects.create(name=ID_GROUP+instance.username)")

            #Create a group into groups_manager_group
            group = Group.objects.create(name=ID_GROUP+instance.username)
            print("group instance created")
            print(group)
            #Add member into the group correct
            group.add_member(member=member)
            print("member added into the group correct")
            #UserObjectPermission.objects.assign_perm('can_add_member_for_xgroup', member, obj=group)
            assign_perm('groups_manager.can_add_member_custom', member, group)

    except Exception as e:
        print("Exception: "+str(e))
        pass


def save_user_profile(sender, instance, **kwargs):
    print("save_user_profile")
    try:
        instance.profile.save()

    except Exception as e:
        print("Exception: "+str(e))
        pass

post_save.connect(create_user_profile, sender=User)
post_save.connect(save_user_profile, sender=User)

@ad-m 我试过这段代码,但我得到了例外。

#Add member into the group correct
            group.add_member(member=member)
            print("member added into the group correct")

            #Assign permission for the groups
            assign_perm('groups_manager.can_add_member_custom', member, group)
            print("assign_perm('groups_manager.can_add_member_custom', member, group)")

screen shot 2017-11-21 at 10 14 30

@Allan-Nava ,您在错误消息中不清楚什么?

@ad-m
我得到了这个错误:

def create_user_profile(sender, instance, created, **kwargs):
    print("create_user_profile")
    try:
        print("created: "+ str(created))
        if created:
            Profile.objects.create(user=instance)
            print("Member.objects.get_or_create(django_user=instance)")
            #Create a user into groups_manager_member
            member = Member.objects.create(django_user=instance, first_name=instance.first_name, last_name=instance.last_name, username=instance.username, email=instance.email)
            print("member instance created")
            print(member)
            print("Group.objects.create(name=ID_GROUP+instance.username)")

            #Create a group into groups_manager_group
            group = Group.objects.create(name=ID_GROUP+instance.username)
            print("group instance created")
            print(group)
            #Add member into the group correct
            group.add_member(member=member)
            print("member added into the group correct")

            #Assign permission for the groups
            assign_perm('groups_manager.can_add_member_custom', instance, group)
            print("assign_perm('groups_manager.can_add_member_custom', instance, group)")

    except Exception as e:
        print("Exception: "+str(e))
        pass

screen shot 2017-11-21 at 12 53 38

@Allan-Nava ,您在错误消息中不清楚什么?

@ad-m 我不明白问题出在哪里

@Allan-Nava ,没有这种许可。 阅读文档什么权限存在

好的,我读了,但是当我创建一个新用户时,我需要为 N 个组/用户创建 N 个权限?

content_type = ContentType.objects.get_for_model(Group)
permission = Permission.objects.create(
    codename='can_add_member_custom',
    name='Can Add Member Custom',
    content_type=content_type,
)

至于说之前

异常是创建一千个权限。

一种操作类型的权限。

正如之前所说:
异常是创建一千个权限。
一种操作类型的权限。

好的,但是我如何创建通用权限?

正如 Django 核心文档所说。 上面有链接。

好的,我使用 Django 组管理器:

这是我的模型

class Group(GroupMixin):

    group_type = models.ForeignKey(GroupType, null=True, blank=True, on_delete=models.SET_NULL,
                                   related_name='%(app_label)s_%(class)s_set')
    group_entities = models.ManyToManyField(GroupEntity, blank=True,
                                            related_name='%(app_label)s_%(class)s_set')

    django_group = models.ForeignKey(DjangoGroup, null=True, blank=True, on_delete=models.SET_NULL)
    group_members = models.ManyToManyField(Member, through='GroupMember',
                                           related_name='%(app_label)s_%(class)s_set')

    # this is just required for easy explanation
    class Meta(GroupMixin.Meta):
        abstract = False
        permissions = (
            ('can_add_member_custom', 'Can Add Member Custom'),
        )

这是我的模型简介

from __future__ import unicode_literals

import hashlib
import os.path
import urllib

from django.conf import settings
from django.contrib.auth.models import User
from django.db import models
from django.db.models.signals import post_save
from django.utils.encoding import python_2_unicode_compatible

from bootcamp.activities.models import Notification
#Custom class - ParentsProfile
from bootcamp.parents.models import ParentsProfile
#Custom class - MemberMixin TO CREATE INTO groups_manager_member
from bootcamp.groups_manager.models import MemberMixin, Member, Group
#Import django guardian assign_perm
from guardian.shortcuts import assign_perm
#import UserObjectPermission
from guardian.models import UserObjectPermission

import datetime

ID_GROUP = "Group_"

'''
User Model - Authentication
'''
<strong i="12">@python_2_unicode_compatible</strong>
class Profile(models.Model):
    user = models.OneToOneField(User)
    location = models.CharField(max_length=50, null=True, blank=True)
    url = models.CharField(max_length=50, null=True, blank=True)
    job_title = models.CharField(max_length=50, null=True, blank=True)

    #I need to delete the parents application

    #Other tascout attributes
    birthdate = models.DateField(default=datetime.date.today)
    address = models.CharField(max_length=255, null=True, blank=True)
    main_role = models.CharField(max_length=255, null=True, blank=True)
    other_roles = models.CharField(max_length=255, null=True, blank=True)
    mobile = models.CharField(max_length=255, null=True, blank=True)
    background_photo = models.CharField(max_length=255, null=True, blank=True)
    profile_photo = models.CharField(max_length=255, null=True, blank=True)
    biography = models.TextField(null=True, blank=True)
    idols = models.TextField(null=True, blank=True)
    weight = models.IntegerField(default=0)
    height = models.IntegerField(default=0)
    favorite_team = models.CharField(max_length=255, null=True, blank=True)
    level = models.IntegerField(default=0)
    sex = models.CharField(max_length=1, default="M")
    nationality = models.CharField(max_length=255, null=True, blank=True)
    city = models.CharField(max_length=255, null=True, blank=True)
    postal_code = models.CharField(max_length=255, null=True, blank=True)
    province = models.CharField(max_length=255, null=True, blank=True)
    number = models.CharField(max_length=255, null=True, blank=True)
    latitude = models.DecimalField( null=True, blank=True, max_digits=9, decimal_places=6)
    longitude = models.DecimalField( null=True, blank=True, max_digits=9, decimal_places=6)

    class Meta:
        db_table = 'auth_profile'

    def __str__(self):
        return self.user.username

    def get_url(self):
        url = self.url
        if "http://" not in self.url and "https://" not in self.url and len(self.url) > 0:  # noqa: E501
            url = "http://" + str(self.url)

        return url

    def get_picture(self):
        no_picture = settings.MEDIA_URL +'/profile_pictures/user.png'
        try:
            filename = settings.MEDIA_ROOT + '/profile_pictures/' +\
                self.user.username + '.jpg'
            picture_url = settings.MEDIA_URL + 'profile_pictures/' +\
                self.user.username + '.jpg'
            if os.path.isfile(filename):  # pragma: no cover
                return picture_url
            else:  # pragma: no cover
                gravatar_url = 'http://www.gravatar.com/avatar/{0}?{1}'.format(
                    hashlib.md5(self.user.email.lower()).hexdigest(),
                    urllib.urlencode({'d': no_picture, 's': '256'})
                    )
                return gravatar_url

        except Exception:
            return no_picture

    #Retrieve users' cover
    def get_cover(self):
        no_cover = settings.MEDIA_ROOT +'profile_covers/cover.jpg'
        try:
            filename = settings.MEDIA_ROOT + '/profile_covers/' +\
                self.user.username + '.jpg'
            cover_url = settings.MEDIA_URL + 'profile_covers/' +\
                self.user.username + '.jpg'
            if os.path.isfile(filename) and os.path.exists(filename):  # pragma: no cover
                if cover_url != None:
                    return cover_url
                else:
                    return no_cover
            else:
                no_cover
        except Exception:
            return no_cover

    def get_screen_name(self):
        try:
            if self.user.get_full_name():
                return self.user.get_full_name()
            else:
                return self.user.username
        except:
            return self.user.username

    def notify_liked(self, feed):
        if self.user != feed.user:
            Notification(notification_type=Notification.LIKED,
                         from_user=self.user, to_user=feed.user,
                         feed=feed).save()

    def unotify_liked(self, feed):
        if self.user != feed.user:
            Notification.objects.filter(notification_type=Notification.LIKED,
                                        from_user=self.user, to_user=feed.user,
                                        feed=feed).delete()

    def notify_commented(self, feed):
        if self.user != feed.user:
            Notification(notification_type=Notification.COMMENTED,
                         from_user=self.user, to_user=feed.user,
                         feed=feed).save()

    def notify_also_commented(self, feed):
        comments = feed.get_comments()
        users = []
        for comment in comments:
            if comment.user != self.user and comment.user != feed.user:
                users.append(comment.user.pk)

        users = list(set(users))
        for user in users:
            Notification(notification_type=Notification.ALSO_COMMENTED,
                         from_user=self.user,
                         to_user=User(id=user), feed=feed).save()

    def notify_favorited(self, question):
        if self.user != question.user:
            Notification(notification_type=Notification.FAVORITED,
                         from_user=self.user, to_user=question.user,
                         question=question).save()

    def unotify_favorited(self, question):
        if self.user != question.user:
            Notification.objects.filter(
                notification_type=Notification.FAVORITED,
                from_user=self.user,
                to_user=question.user,
                question=question).delete()

    def notify_answered(self, question):
        if self.user != question.user:
            Notification(notification_type=Notification.ANSWERED,
                         from_user=self.user,
                         to_user=question.user,
                         question=question).save()

    def notify_accepted(self, answer):
        if self.user != answer.user:
            Notification(notification_type=Notification.ACCEPTED_ANSWER,
                         from_user=self.user,
                         to_user=answer.user,
                         answer=answer).save()

    def unotify_accepted(self, answer):
        if self.user != answer.user:
            Notification.objects.filter(
                notification_type=Notification.ACCEPTED_ANSWER,
                from_user=self.user,
                to_user=answer.user,
                answer=answer).delete()

def create_user_profile(sender, instance, created, **kwargs):
    print("create_user_profile")
    try:
        print("created: "+ str(created))
        if created:
            Profile.objects.create(user=instance)
            print("Member.objects.get_or_create(django_user=instance)")
            #Create a user into groups_manager_member
            member = Member.objects.create(django_user=instance, first_name=instance.first_name, last_name=instance.last_name, username=instance.username, email=instance.email)
            print("member instance created")
            print(member)
            print("Group.objects.create(name=ID_GROUP+instance.username)")

            #Create a group into groups_manager_group
            group = Group.objects.create(name=ID_GROUP+instance.username)
            print("group instance created")
            print(group)
            #Add member into the group correct
            group.add_member(member=member)
            print("member added into the group correct")

            #Assign permission for the groups
            assign_perm('can_add_member_custom', instance, group)
            #print("assign_perm('can_add_member_custom', instance, group)")

    except Exception as e:
        print("Exception: "+str(e))
        pass


def save_user_profile(sender, instance, **kwargs):
    print("save_user_profile")
    try:
        instance.profile.save()

    except Exception as e:
        print("Exception: "+str(e))
        pass

post_save.connect(create_user_profile, sender=User)
post_save.connect(save_user_profile, sender=User)

Django-guardian 是按单个对象权限管理的,所以给单个对象授予单个用户/组权限。

好的,完美,但仍然无法正常工作,尽管我在模型组中添加了权限

什么不起作用?

这一行:

#Assign permission for the groups
            assign_perm('can_add_member_custom', instance, group)
            print("assign_perm('can_add_member_custom', instance, group)")

实例是用户对象,但我将权限添加到组模型中

# this is just required for easy explanation
    class Meta(GroupMixin.Meta):
        abstract = False
        permissions = (
            ('can_add_member_custom', 'Can Add Member Custom'),
        )

我使用了这个django-groups-manager

我很愚蠢,我必须进行迁移和迁移:

python3 manage.py makemigrations
python3 manage.py migrate

感谢您的耐心👍 @ad-m

但是在模板视图中,我如何检查?
这个:
jack.has_perm('change_group', admins)

使用django shell,它可以工作:
screen shot 2017-11-21 at 16 42 17

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

lukaszb picture lukaszb  ·  14评论

Allan-Nava picture Allan-Nava  ·  4评论

Dzejkob picture Dzejkob  ·  28评论

brianmay picture brianmay  ·  16评论

g-as picture g-as  ·  10评论