Django-guardian: Menggunakan assign_perm dalam migrasi Django 1.7

Dibuat pada 13 Nov 2014  ·  10Komentar  ·  Sumber: django-guardian/django-guardian

Perhatikan kode migrasi berikut:

from django.db import models, migrations
from guardian.shortcuts import assign_perm

def assign_perms(apps, schema_editor):
    Group = apps.get_model("auth", "Group")
    for group in Group.objects.all():
        assign_perm('products.view_product', group)
        # assign_perm('products.view_product', group, product)

class Migration(migrations.Migration):

    operations = [
        migrations.RunPython(assign_perms),
    ]

Saat menerapkan migrasi ini, panggilan assign_perm memberikan kesalahan:

guardian.exceptions.NotUserNorGroup: User/AnonymousUser or Group instance is required (got Group object)

Komentar yang paling membantu

Saya memposting ini di sini jika itu berguna untuk orang lain, tetapi saya menulis metode assign_perm relatif umum ini untuk migrasi pengaturan awal, membuat beberapa asumsi tetapi mungkin membantu:

def assign_perm(perm, user_or_group, obj=None, apps=None):
    permission_model = apps.get_model('auth', 'Permission')
    permission = permission_model.objects.get(codename=perm)

    # Assumes object permission models live in the same app as the model they govern
    # and are named like `ProjectUserObjectPermission`/`ProjectGroupObjectPermission`
    obj_permission_model = apps.get_model(obj._meta.app_label, '{}{}ObjectPermission'.format(
        obj._meta.object_name,
        user_or_group._meta.object_name,
    ))
    obj_permission_model.objects.create(
        # `object_pk` and `content_type_id` keys if you're not using direct foreign keys
        # https://django-guardian.readthedocs.io/en/stable/userguide/performance.html#direct-foreign-keys
        content_object=obj,
        permission=permission,
        **{
            user_or_group._meta.model_name: user_or_group
        }
    )

Semua 10 komentar

+1

+1

+1

Saya memperbaiki kesalahan ini dengan mengimpor Group dari django.contrib.auth , namun sekarang tampaknya tidak membuat perubahan apa pun dalam database (lihat #333). Itu ada di Django 1.8 dan guardian 1.3 jadi jika seseorang bisa mencoba di 1.7 itu akan bagus

Saya akhirnya menggunakan dua fungsi pembantu untuk skrip migrasi:
https://Gist.github.com/xuhcc/67871719116bdc0fee6c
(penjaga-django==1.2.5)

Masih tidak ada cinta dengan 1.8/1.3 sayangnya. Menggunakan fungsi pembantu Anda, saya mendapatkan kesalahan
ValueError: Cannot query "project": Must be "ContentType" instance di

perm = Permission.objects.get(
            content_type=get_content_type(obj),
            codename=codename)

obj adalah turunan dari model bernama proyek yang saya dapatkan seperti ini:

projs = get_objects_for_user(user, 'api.view_project')
        for proj in projs:
                assign_perm(apps, 'api.edit_project', user, proj)

Sayangnya, menggunakan assign_perms di dalam migrasi (atau kode lain yang bergantung pada skema yang tidak ada dalam migrasi itu sendiri) adalah ide yang sangat buruk. Saya tidak terkejut itu tidak berhasil juga.

Alasan itu tidak bekerja kemungkinan besar dalam logika untuk menemukan model izin tidak menggunakan model yang benar dikembalikan oleh apps.get_model() diperlukan untuk migrasi. Ini mungkin bisa diperbaiki.

Namun, ada masalah mendasar di sini yang tidak dapat dipecahkan. Itu adalah migrasi database jangan mencoba untuk membuat serial dari fungsi assign_perm() atau salah satu fungsi yang dipanggil assign_perm() . Jadi versi Django-guardian yang lebih baru dapat mengubah skema basis data dan memperbarui assign_perm() untuk menggunakan skema baru. Migrasi lama Anda akan tiba-tiba rusak karena sekarang menjalankan kode assign_perm() dengan skema database lama.

Bahkan, mungkin saja beberapa fitur yang diminta, seperti peran, memerlukan perubahan skema ini.

Ini mungkin bukan jawaban yang Anda cari, namun saya pikir Anda harus menggunakan operasi basis data tingkat rendah untuk mengatur izin. Maksud saya interaksi langsung dengan model Izin db. Migrasi Django seharusnya tidak mengakses fungsi yang bergantung pada skema basis data di luar migrasi. Ini termasuk fungsi kustom pada kelas model db juga.

Mungkin batasan ini dapat didokumentasikan dengan lebih baik. Tarik permintaan dihargai.

Dengan demikian menutup bug ini.

Halo
saya memiliki masalah yang sama dengan versi 1.4.4 pf guardian dan Django 1.9.7
assign_perm apa pun di dalam migrasi tidak berfungsi ... :(
adakah yang tahu bagaimana itu bisa diperbaiki sepenuhnya atau monyet ditambal di dalam migrasi?

Alasan itu tidak bekerja kemungkinan besar dalam logika untuk menemukan model izin tidak menggunakan model yang benar dikembalikan oleh apps.get_model() diperlukan untuk migrasi. Ini mungkin bisa diperbaiki.

Mungkin grup auth dapat dibungkus untuk berperilaku seperti grup wali.

Saya memposting ini di sini jika itu berguna untuk orang lain, tetapi saya menulis metode assign_perm relatif umum ini untuk migrasi pengaturan awal, membuat beberapa asumsi tetapi mungkin membantu:

def assign_perm(perm, user_or_group, obj=None, apps=None):
    permission_model = apps.get_model('auth', 'Permission')
    permission = permission_model.objects.get(codename=perm)

    # Assumes object permission models live in the same app as the model they govern
    # and are named like `ProjectUserObjectPermission`/`ProjectGroupObjectPermission`
    obj_permission_model = apps.get_model(obj._meta.app_label, '{}{}ObjectPermission'.format(
        obj._meta.object_name,
        user_or_group._meta.object_name,
    ))
    obj_permission_model.objects.create(
        # `object_pk` and `content_type_id` keys if you're not using direct foreign keys
        # https://django-guardian.readthedocs.io/en/stable/userguide/performance.html#direct-foreign-keys
        content_object=obj,
        permission=permission,
        **{
            user_or_group._meta.model_name: user_or_group
        }
    )
Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

g-as picture g-as  ·  10Komentar

David-OConnor picture David-OConnor  ·  6Komentar

johnthagen picture johnthagen  ·  9Komentar

lukaszb picture lukaszb  ·  14Komentar

Allan-Nava picture Allan-Nava  ·  4Komentar