Django-guardian: Bagaimana cara mengoptimalkan kueri saya saat menggunakan `assign_perm`?

Dibuat pada 20 Agu 2020  ·  2Komentar  ·  Sumber: django-guardian/django-guardian

Saat ini saya sedang mengerjakan proyek di mana satu ruangan memiliki izin grupnya sendiri.

Ketika seseorang membuat ruangan baru, sistem akan melakukan hal berikut:

  1. Membuat ruangan
  2. Buat grup pemilik dan staf dengan nama unik, seperti Room Owner#room#{pk}
  3. Dapatkan daftar izin pemilik dan staf dari kelas Kamar
  4. Buatlah tugas untuk setiap kelompok
  5. Tetapkan izin grup pemilik kepada pengguna

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,

Komentar yang paling membantu

  1. Gunakan kunci asing langsung, lihat https://django-guardian.readthedocs.io/en/stable/userguide/performance.html#direct -foreign-keys

  2. Anda dapat meneruskan instance Permission ke assign_perm . perm = self._get_permission_string(owner_perm) mengarah ke kueri tambahan per izin.

  3. 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)

Semua 2 komentar

  1. Gunakan kunci asing langsung, lihat https://django-guardian.readthedocs.io/en/stable/userguide/performance.html#direct -foreign-keys

  2. Anda dapat meneruskan instance Permission ke assign_perm . perm = self._get_permission_string(owner_perm) mengarah ke kueri tambahan per izin.

  3. 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,

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

xuhcc picture xuhcc  ·  10Komentar

Allan-Nava picture Allan-Nava  ·  4Komentar

brianmay picture brianmay  ·  16Komentar

ad-m picture ad-m  ·  13Komentar

BenDevelopment picture BenDevelopment  ·  5Komentar