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 ์ฝ”์–ด์— ํ•ด๋‹น๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฃน X์— ๋Œ€ํ•ด ๊ด€๋ฆฌ ๊ทธ๋ฃน X์— ๋ถ€์—ฌ๋œ ์˜ฌ๋ฐ”๋ฅธ Django-guardian ๊ถŒํ•œ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๊ทธ๋ฃน 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) ์ด๋ฉด ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ํŠน์ • ๊ทธ๋ฃน์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ข‹์•„์š”, ํ•˜์ง€๋งŒ ํ…œํ”Œ ๋ณด๊ธฐ์—์„œ ์–ด๋–ป๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‚˜์š”?

{{ 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 Groups Manager๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค:

์ด๊ฒƒ์€ ๋‚ด ๋ชจ๋ธ ๊ทธ๋ฃน์ž…๋‹ˆ๋‹ค .

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 ์…ธ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
screen shot 2017-11-21 at 16 42 17

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰

๊ด€๋ จ ๋ฌธ์ œ

Dzejkob picture Dzejkob  ยท  28์ฝ”๋ฉ˜ํŠธ

BenDevelopment picture BenDevelopment  ยท  5์ฝ”๋ฉ˜ํŠธ

Allan-Nava picture Allan-Nava  ยท  4์ฝ”๋ฉ˜ํŠธ

David-OConnor picture David-OConnor  ยท  6์ฝ”๋ฉ˜ํŠธ

g-as picture g-as  ยท  10์ฝ”๋ฉ˜ํŠธ