Django-guardian: Utilisation d'assign_perm dans la migration django 1.7

Créé le 13 nov. 2014  ·  10Commentaires  ·  Source: django-guardian/django-guardian

Considérez le code de migration suivant :

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),
    ]

Lors de l'application de cette migration, l'appel assign_perm génère une erreur :

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

Commentaire le plus utile

Je poste ceci ici au cas où cela serait utile pour quelqu'un d'autre, mais j'ai écrit cette méthode assign_perm relativement générique pour une migration de configuration initiale, fait quelques hypothèses mais probablement utile :

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
        }
    )

Tous les 10 commentaires

+1

+1

+1

J'ai corrigé cette erreur en important Group partir de django.contrib.auth , mais il ne semble plus apporter aucune modification à la base de données (voir #333). C'est sur Django 1.8 et Guardian 1.3, donc si quelqu'un pouvait essayer la 1.7, ce serait génial

J'ai fini par utiliser deux fonctions d'assistance pour les scripts de migration :
https://gist.github.com/xuhcc/67871719116bdc0fee6c
(django-gardien==1.2.5)

Toujours pas d'amour avec 1,8/1,3 malheureusement. En utilisant vos fonctions d'assistance, j'obtiens l'erreur
ValueError: Cannot query "project": Must be "ContentType" instance à

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

obj est une instance d'un modèle nommé project que j'obtiens comme ceci :

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

Malheureusement, utiliser assign_perms dans les migrations (ou tout autre code dépendant du schéma ne faisant pas partie de la migration elle-même) est une très mauvaise idée. Je ne suis pas surpris que cela ne fonctionne pas non plus.

La raison pour laquelle cela ne fonctionne pas, c'est très probablement dans la logique de trouver le modèle d'autorisation n'utilise pas le modèle correct renvoyé par apps.get_model() requis pour la migration. Cela pourrait être réparable.

Cependant, il y a ici un problème fondamental qui ne peut pas être résolu. C'est-à-dire que les migrations de base de données ne tentent pas de sérialiser la fonction assign_perm() ou l'une des fonctions appelées assign_perm() . Ainsi, une version ultérieure de django-guardian pourrait modifier le schéma de la base de données et mettre assign_perm() jour assign_perm() avec l'ancien schéma de base de données.

En fait, il est possible que certaines des fonctionnalités demandées, telles que les rôles, nécessitent ce changement dans le schéma.

Ce n'est probablement pas la réponse que vous cherchiez, mais je pense que vous devez utiliser des opérations de base de données de niveau inférieur pour définir les autorisations. J'entends par là directement l'interaction avec les modèles Permission db. Les migrations Django ne doivent pas accéder aux fonctions dépendantes du schéma de la base de données en dehors de la migration. Cela inclut également des fonctions personnalisées sur la classe de modèle db.

Peut-être que cette limitation pourrait être mieux documentée. Les demandes de tirage sont appréciées.

En tant que tel, fermeture de ce bogue.

Bonjour
j'ai le même problème avec la version 1.4.4 pf guardian et django 1.9.7
aucune assign_perm à l'intérieur des migrations ne fonctionne... :(
est-ce une idée de comment cela peut-il être totalement corrigé ou corrigé par un singe dans les migrations?

La raison pour laquelle cela ne fonctionne pas, c'est très probablement dans la logique de trouver le modèle d'autorisation n'utilise pas le modèle correct renvoyé par apps.get_model() requis pour la migration. Cela pourrait être réparable.

Peut-être que les groupes d'autorisation pourraient être encapsulés pour se comporter comme un groupe de gardiens.

Je poste ceci ici au cas où cela serait utile pour quelqu'un d'autre, mais j'ai écrit cette méthode assign_perm relativement générique pour une migration de configuration initiale, fait quelques hypothèses mais probablement utile :

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
        }
    )
Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

johnthagen picture johnthagen  ·  9Commentaires

ad-m picture ad-m  ·  13Commentaires

BenDevelopment picture BenDevelopment  ·  5Commentaires

Allan-Nava picture Allan-Nava  ·  4Commentaires

lukaszb picture lukaszb  ·  14Commentaires