أنا أعمل حاليًا على مشروع حيث تمتلك غرفة واحدة أذونات المجموعة الخاصة بها.
عندما يقوم شخص ما بإنشاء غرفة جديدة ، فسيقوم النظام بما يلي:
Room Owner#room#{pk}
هذا هو نموذج غرفتي:
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)
عندما ألقي نظرة على سجلات الاستعلام ، هناك الكثير من الاستعلامات التي يتم إجراؤها في هذه العملية.
في الواقع ، لا يزال هناك عدد قليل من المجموعات وعملية التعيين على النحو الوارد أعلاه ، لكنني قمت فقط بتضمين أمثلة قليلة ، لذلك ليس هناك الكثير ، إذا تم حسابها ، فقد يكون هناك أكثر من 50 عملية تنفيذ استعلام يتم تشغيلها في هذه العملية.
لذا ، كيف يمكنني تحسين الاستعلام لهذه المشكلة؟ يمكن لأي شخص أن يشارك كيفية القيام بذلك بشكل أفضل.
شكرا لك،
استخدم المفاتيح الخارجية المباشرة ، راجع https://django-guardian.readthedocs.io/en/stable/userguide/performance.html#direct -foreign-keys
يمكنك تمرير مثيلات من Permission
إلى assign_perm
. perm = self._get_permission_string(owner_perm)
إلى استعلام إضافي لكل إذن.
إذا لم يكن هذا كافيًا ، يمكنك تعيين الأذونات بشكل مجمّع ، انظر الرمز أدناه. لكن كن على علم بأنني لم أختبر هذا الرمز. قد يحتاج إلى تعديلات ، قد لا يعمل على الإطلاق.
قبل:
# 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)
يا إلهي. لقد فاتني هذا. قررت استخدام الأول. شكرا لك،
التعليق الأكثر فائدة
استخدم المفاتيح الخارجية المباشرة ، راجع https://django-guardian.readthedocs.io/en/stable/userguide/performance.html#direct -foreign-keys
يمكنك تمرير مثيلات من
Permission
إلىassign_perm
.perm = self._get_permission_string(owner_perm)
إلى استعلام إضافي لكل إذن.إذا لم يكن هذا كافيًا ، يمكنك تعيين الأذونات بشكل مجمّع ، انظر الرمز أدناه. لكن كن على علم بأنني لم أختبر هذا الرمز. قد يحتاج إلى تعديلات ، قد لا يعمل على الإطلاق.
قبل:
بعد، بعدما: