Django REPOS cadre de l'objet des autorisations de niveau
Je suis en utilisant Django REPOS Cadre d'accéder à une ressource 'utilisateur'.
Que l'utilisateur l'information qui est personnel, je ne veux pas d'une requête GET à la liste de tous les utilisateurs du système, SAUF si elles sont un admin.
Si l'utilisateur spécifie une pièce d'identité, et ils sont connecté, je voudrais être en mesure de visualiser leurs données et de les modifier (METTRE des POST SUPPRIMER) si nécessaire.
Donc en résumé, dis-permettre à méthode GET pour quelqu'un qui n'est pas un admin et GET POST SUPPRIMER METTRE sur les utilisateurs connectés lors de l'affichage de leurs informations.
j'ai donc créé la coutume d'autorisation classe:
class UserPermissions(permissions.BasePermission):
"""
Owners of the object or admins can do anything.
Everyone else can do nothing.
"""
def has_permission(self, request, view):
# if admin: True otherwise False
def has_object_permission(self, request, view, obj):
# if request.user is the same user that is contained within the obj then allow
Cela n'a pas fonctionné. Après un peu de débogage, j'ai trouvé qu'il vérifie has_permission d'abord, PUIS vérifie has_object_permission. Donc, si nous n'avons pas obtenir passé ce premier obstacle OBTENIR /utilisateur/, alors il n'est pas même envisager la prochaine GET /utilisateur/id.
donc En résumé, personne ne sait comment s'y prendre pour que cela fonctionne?
Merci 🙂
EDIT:
J'ai été en utilisant ModelViewSets, qui ont ce problème comme je l'ai décrit.
Mais si vous divisez la fonctionnalité de Liste avec le Détail ensuite, vous pouvez leur donner une autre autorisation classes:
class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes=(UserPermissionsAll,)
class UserDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes=(UserPermissionsObj,)
class UserPermissionsAll(permissions.BasePermission):
"""
Owners of the object or admins can do anything.
Everyone else can do nothing.
"""
def has_permission(self, request, view):
if request.user.is_staff:
return True
else:
return False
class UserPermissionsObj(permissions.BasePermission):
"""
Owners of the object or admins can do anything.
Everyone else can do nothing.
"""
def has_object_permission(self, request, view, obj):
if request.user.is_staff:
return True
return obj == request.user
- La solution ci-dessous à partir de produits Chimiques Programmeur travaillera avec
viewsets
.
Vous devez vous connecter pour publier un commentaire.
Je l'ai fait dans le passé en utilisant une autorisation personnalisée et remplacé
has_object_permission
comme suit:Vous pouvez faire un peu plus détaillée des choses telles que de refuser une demande spécifique de types (par exemple pour permettre d'OBTENIR les demandes de tous les utilisateurs):
Alors à votre avis que vous donnez à utiliser les autorisations de classe:
J'ai un besoin similaire. Permet d'appeler mon app
x
. Voici ce que j'ai trouvé.D'abord, mettez ceci dans
x/viewsets.py
:Puis dans
x/permissions.py
:Puis dans
x/views.py
:En passant, notez que vous pouvez utiliser un différents sérialiseur pour ces deux viewsets, ce qui signifie que vous pouvez afficher différents attributs dans le
list
vue que dans leretrieve
vue! Par exemple:Puis dans
x/urls.py
:J'ai été légèrement surpris de voir que
router
accepté le même modèle à deux reprises, mais il ne semble fonctionner.Caveat lector: j'ai confirmé tout cela fonctionne via l'API du navigateur, mais je n'ai pas essayé mise à jour via l'API encore.
Pour le faux upons, le la documentation dans les restrictions de niveau de l'objet de l'autorisation dit:
Donc, la vue détails fonctionne, mais pour la liste, vous aurez besoin de filtre à contre-courant de l'utilisateur.
Juste une chose à @will-hart réponse.
Dans DRF3 documentation,
Par conséquent,
has_permission
doit être spécifié à utiliserhas_object_permission
.Toutefois, le code ci-dessus donne la permission à personne lorsque l'utilisateur tente de récupérer la liste de l'utilisateur. Dans ce cas, il serait préférable de donner la permission selon
action
, pas laHTTP method
.