Django-guardian: إضافة / إزالة عضو فقط لمجموعة معينة

تم إنشاؤها على ٢٠ نوفمبر ٢٠١٧  ·  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" ، أرغب في إنشاء إذن جديد يسمى "Can add group for 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 لمجموعات / مستخدمين عندما أقوم بإنشاء مستخدم جديد؟

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 هو لكل كائن منفرد إدارة إذن ، لذا امنح مستخدمًا واحدًا / مجموعة إذنًا لكائن واحد.

حسنًا ، رائع ، لكن لا يزال لا يعمل على الرغم من أنني أضفت الإذن في Model Group

ما الذي لا يعمل؟

هذا الخط:

#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 هذا

أنا غبي ، لا بد لي من الهجرة والهجرة:

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 التقييمات

القضايا ذات الصلة

Allan-Nava picture Allan-Nava  ·  4تعليقات

ad-m picture ad-m  ·  13تعليقات

g-as picture g-as  ·  10تعليقات

johnthagen picture johnthagen  ·  9تعليقات

BenDevelopment picture BenDevelopment  ·  5تعليقات