Saat ini saya sedang mengerjakan proyek di mana satu ruangan memiliki izin grupnya sendiri.
Ketika seseorang membuat ruangan baru, sistem akan melakukan hal berikut:
Room Owner#room#{pk}
Ini model kamar saya:
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', _('...'))
]
]
Ini adalah kode saya untuk membuat ruang dan menghasilkan izin grup:
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)
Ketika saya melihat log kueri, ada banyak kueri yang dilakukan dalam proses ini.
Sebenarnya masih ada beberapa grup dan proses penugasan seperti di atas, tapi saya hanya menyertakan beberapa contoh saja, jadi tidak terlalu banyak. Jika dihitung, mungkin ada lebih dari 50 eksekusi query yang berjalan dalam proses ini.
Jadi, bagaimana saya bisa mengoptimalkan kueri untuk masalah ini? Adakah yang bisa berbagi bagaimana melakukannya dengan lebih baik.
Terima kasih,
Gunakan kunci asing langsung, lihat https://django-guardian.readthedocs.io/en/stable/userguide/performance.html#direct -foreign-keys
Anda dapat meneruskan instance Permission
ke assign_perm
. perm = self._get_permission_string(owner_perm)
mengarah ke kueri tambahan per izin.
Jika ini tidak cukup, Anda dapat menetapkan izin secara massal, lihat kode di bawah. Tetapi perlu diketahui bahwa saya tidak menguji kode ini. Mungkin perlu penyesuaian, mungkin tidak berfungsi sama sekali.
Sebelum:
# 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)
Setelah:
# 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)
Ya Tuhan. Aku merindukan yang satu ini. Saya memutuskan untuk menggunakan yang pertama. Terima kasih,
Komentar yang paling membantu
Gunakan kunci asing langsung, lihat https://django-guardian.readthedocs.io/en/stable/userguide/performance.html#direct -foreign-keys
Anda dapat meneruskan instance
Permission
keassign_perm
.perm = self._get_permission_string(owner_perm)
mengarah ke kueri tambahan per izin.Jika ini tidak cukup, Anda dapat menetapkan izin secara massal, lihat kode di bawah. Tetapi perlu diketahui bahwa saya tidak menguji kode ini. Mungkin perlu penyesuaian, mungkin tidak berfungsi sama sekali.
Sebelum:
Setelah: