Django-guardian: 'рдЕрд╕рд╛рдЗрди_рдкрд░реНрдо' рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдореИрдВ рдЕрдкрдиреА рдХреНрд╡реЗрд░реА рдХреЛ рдХреИрд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ?

рдХреЛ рдирд┐рд░реНрдорд┐рдд 20 рдЕрдЧре░ 2020  ┬╖  2рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: django-guardian/django-guardian

рдореИрдВ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдПрдХ рдРрд╕реЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдБ рдЬрд╣рд╛рдБ рдПрдХ рдХрдорд░реЗ рдХреА рдЕрдкрдиреА рд╕рдореВрд╣ рдЕрдиреБрдорддрд┐рдпрд╛рдБ рд╣реИрдВред

рдЬрдм рдХреЛрдИ рдирдпрд╛ рдХрдорд░рд╛ рдмрдирд╛рддрд╛ рд╣реИ, рддреЛ рд╕рд┐рд╕реНрдЯрдо рдирд┐рдореНрди рдХрд╛рд░реНрдп рдХрд░реЗрдЧрд╛:

  1. рдПрдХ рдХрдорд░рд╛ рдмрдирд╛рдирд╛
  2. рдЕрджреНрд╡рд┐рддреАрдп рдирд╛рдореЛрдВ рд╡рд╛рд▓реЗ рд╕реНрд╡рд╛рдореА рдФрд░ рдХрд░реНрдордЪрд╛рд░реА рд╕рдореВрд╣ рдмрдирд╛рдПрдВ, рдЬреИрд╕реЗ Room Owner#room#{pk}
  3. рд░реВрдо рдХреНрд▓рд╛рд╕ рд╕реЗ рдорд╛рд▓рд┐рдХ рдФрд░ рд╕реНрдЯрд╛рдл рдХреА рдЕрдиреБрдорддрд┐рдпреЛрдВ рдХреА рд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ
  4. рдкреНрд░рддреНрдпреЗрдХ рд╕рдореВрд╣ рдХреЛ рдПрдХ рдирд┐рдпрдд рдХрд╛рд░реНрдп рдХрд░реЗрдВ
  5. рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╕реНрд╡рд╛рдореА рд╕рдореВрд╣ рдЕрдиреБрдорддрд┐рдпрд╛рдБ рдЕрд╕рд╛рдЗрди рдХрд░реЗрдВ

рдпрд╣рд╛рдБ рдореЗрд░рд╛ рдХрдХреНрд╖ рдореЙрдбрд▓ рд╣реИ:

class Room(models.Model):
    # ...fields

    PERMISSION_GROUPS = [
        'owner': [
            ('view_room', _('...')),
            ('change_room', _('...')),
            ('delete_room', _('...')),

            ('open_room', _('...')),
            ('close_room', _('...'))
        ],
        'staff': [
            ('view_room', _('...')),
            ('open_room', _('...')),
            ('close_room', _('...'))    
        ]
    ]

рдпрд╣ рдХрдорд░рд╛ рдмрдирд╛рдиреЗ рдФрд░ рд╕рдореВрд╣ рдЕрдиреБрдорддрд┐рдпрд╛рдБ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореЗрд░рд╛ рдХреЛрдб рд╣реИ:

from guardian.shortcuts import assign_perm

class CreateRoomView(generics.CreateAPIView):
    def _get_permission_string(self, perm):
        """
        Get string permission, the return is like 'room.add_room'
        """
        return f'room.{perm.codename}'

    def post(self):
        # Create a room
        body = {}
        room = Room.objects.create(**body)

        # Get content type
        ctype = ContentType.objects.get_for_model(Room)

        # Define name of owner and staff group for this room permission
        owner_group_name = _('Room Owner#room#{pk}')
        staff_group_name = _('Room Staff#room#{pk}')

        # Create group
        owner_group = Group.objects.create(
            name=owner_group_name.format(pk=room.pk))
        staff_group = Group.objects.create(
            name=staff_group_name.format(pk=room.pk))

        # Get permissions by group permissions
        owner_perms = Permission.objects.filter(
            codename__in=Room.PERMISSION_GROUPS.get('owner'), content_type=ctype)
        staff_perms = Permission.objects.filter(
            codename__in=Room.PERMISSION_GROUPS.get('staff'), content_type=ctype)

        # Assign owner permissions to the group
        for owner_perm in owner_perms:
            perm = self._get_permission_string(owner_perm)
            assign_perm(perm, owner_group, obj=room)

        # Assign staff permissions to the group
        for staff_perm in staff_perms:
            perm = self._get_permission_string(staff_perm)
            assign_perm(perm, staff_group, obj=room)

        # Assign owner group permission to the user
        request.user.groups.add(owner_group)

рдЬрдм рдореИрдВ рдХреНрд╡реЗрд░реА рд▓реЙрдЧ рджреЗрдЦрддрд╛ рд╣реВрдВ, рддреЛ рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдкреНрд░рд╢реНрди рдХрд┐рдП рдЬрд╛ рд░рд╣реЗ рд╣реИрдВред

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдКрдкрд░ рдХреА рддрд░рд╣ рдЕрднреА рднреА рдХреБрдЫ рд╕рдореВрд╣ рдФрд░ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдХреЗрд╡рд▓ рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг рд╢рд╛рдорд┐рд▓ рдХрд┐рдП рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдмрд╣реБрдд рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реИрдВред рдпрджрд┐ рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ, рддреЛ рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ релреж рд╕реЗ рдЕрдзрд┐рдХ рдХреНрд╡реЗрд░реА рдирд┐рд╖реНрдкрд╛рджрди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред

рддреЛ, рдореИрдВ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЗ рд▓рд┐рдП рдХреНрд╡реЗрд░реА рдХреЛ рдХреИрд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ? рдХреНрдпрд╛ рдХреЛрдИ рдЗрд╕реЗ рдмреЗрд╣рддрд░ рддрд░реАрдХреЗ рд╕реЗ рд╕рд╛рдЭрд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рд╢реБрдХреНрд░рд┐рдпрд╛,

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

  1. рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд┐рджреЗрд╢реА рдХреБрдВрдЬрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рджреЗрдЦреЗрдВ https://django-guardian.readthedocs.io/en/stable/userguide/performance.html#direct -foreign-keys

  2. рдЖрдк Permission рд╕реЗ assign_perm рдЙрджрд╛рд╣рд░рдг рдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред perm = self._get_permission_string(owner_perm) рдкреНрд░рддрд┐ рдЕрдиреБрдорддрд┐ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреНрд╡реЗрд░реА рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИред

  3. рдпрджрд┐ рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ рддреЛ рдЖрдк рдмрд▓реНрдХ рдореЗрдВ рдЕрдиреБрдорддрд┐рдпрд╛рдВ рдЕрд╕рд╛рдЗрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдиреАрдЪреЗ рдХреЛрдб рджреЗрдЦреЗрдВред рд▓реЗрдХрд┐рди рдзреНрдпрд╛рди рд░рдЦреЗрдВ рдХрд┐ рдореИрдВрдиреЗ рдЗрд╕ рдХреЛрдб рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд┐рдпрд╛ред рдЗрд╕реЗ рд╕рдорд╛рдпреЛрдЬрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред


рдкрд╣рд▓реЗ:

# Assign owner permissions to the group
for owner_perm in owner_perms:
    perm = self._get_permission_string(owner_perm)
    assign_perm(perm, owner_group, obj=room)

# Assign staff permissions to the group
for staff_perm in staff_perms:
    perm = self._get_permission_string(staff_perm)
    assign_perm(perm, staff_group, obj=room)

рдмрд╛рдж рдореЗрдВ:

# RoomGroupObjectPermission is the model from suggestion 1, use direct foreign keys
room_group_object_permissions = [
    RoomGroupObjectPermission(
        permission=owner_perm, group=owner_group, content_object=room,
    )
    for owner_perm in owner_perms
] + [
    RoomGroupObjectPermission(
        permission=staff_perm, group=staff_group, content_object=room,
    )
    for staff_perm in staff_perms
]

RoomGroupObjectPermission.objects.bulk_create(room_group_object_permissions)

рд╕рднреА 2 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

  1. рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд┐рджреЗрд╢реА рдХреБрдВрдЬрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рджреЗрдЦреЗрдВ https://django-guardian.readthedocs.io/en/stable/userguide/performance.html#direct -foreign-keys

  2. рдЖрдк Permission рд╕реЗ assign_perm рдЙрджрд╛рд╣рд░рдг рдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред perm = self._get_permission_string(owner_perm) рдкреНрд░рддрд┐ рдЕрдиреБрдорддрд┐ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреНрд╡реЗрд░реА рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИред

  3. рдпрджрд┐ рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ рддреЛ рдЖрдк рдмрд▓реНрдХ рдореЗрдВ рдЕрдиреБрдорддрд┐рдпрд╛рдВ рдЕрд╕рд╛рдЗрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдиреАрдЪреЗ рдХреЛрдб рджреЗрдЦреЗрдВред рд▓реЗрдХрд┐рди рдзреНрдпрд╛рди рд░рдЦреЗрдВ рдХрд┐ рдореИрдВрдиреЗ рдЗрд╕ рдХреЛрдб рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд┐рдпрд╛ред рдЗрд╕реЗ рд╕рдорд╛рдпреЛрдЬрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред


рдкрд╣рд▓реЗ:

# Assign owner permissions to the group
for owner_perm in owner_perms:
    perm = self._get_permission_string(owner_perm)
    assign_perm(perm, owner_group, obj=room)

# Assign staff permissions to the group
for staff_perm in staff_perms:
    perm = self._get_permission_string(staff_perm)
    assign_perm(perm, staff_group, obj=room)

рдмрд╛рдж рдореЗрдВ:

# RoomGroupObjectPermission is the model from suggestion 1, use direct foreign keys
room_group_object_permissions = [
    RoomGroupObjectPermission(
        permission=owner_perm, group=owner_group, content_object=room,
    )
    for owner_perm in owner_perms
] + [
    RoomGroupObjectPermission(
        permission=staff_perm, group=staff_group, content_object=room,
    )
    for staff_perm in staff_perms
]

RoomGroupObjectPermission.objects.bulk_create(room_group_object_permissions)

рд╣реЗ рднрдЧрд╡рд╛рдиред рдореБрдЭреЗ рдпрд╣ рдпрд╛рдж рдЖ рдЧрдпрд╛ред рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╡рд╛рд▓реЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рд╢реБрдХреНрд░рд┐рдпрд╛,

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕