2014-09-15 4 views
6

Quando una richiesta GET arriva al backend API a /obj/1Come restituire i dati con errore 403 in Django Rest Framework?

verifico una classe autorizzazioni personalizzate per vedere se l'utente ha accesso, in caso contrario, un 403 viene inviato indietro.

Tuttavia, desidero allegare l'ID oggetto in modo che l'utente possa fare clic su un pulsante sul front-end per richiedere l'accesso.

La mia attuale implementazione è di ignorare il metodo retrieve e "manualmente" controllare l'autorizzazione lì.

Permessi semplificato

class CustomPerm(...): 
    def has_object_permission(...): 
     return request.user.is_staff 

Viewset

class CustomViewSet(...): 
    model = Model 
    permission_classes = (CustomPerm,) 

    def retrieve(self, request, pk=None): 
     obj = get_object_or_404(Model, pk=pk) 

     has_perm = CustomPerm().has_object_permission(request, self, obj=obj) 
     if not has_perm: 
      data = { 'id': obj.id } 
      return Response(data, status=403) 

     return super(ModelViewSet, self).retrieve(request, pk=pk) 

Quindi il mio metodo attuale, has_perm restituisce un QuerySet di utenti, invece di un valore booleano come definito nel metodo delle autorizzazioni. Come mai?

C'è un approccio più pulito a questo?

risposta

16
from rest_framework import permissions 
from rest_framework.exceptions import PermissionDenied 

class CustomPerm(permissions.BasePermission): 
    def has_object_permission(self, request, view, obj): 
     if request.user.is_staff: 
      return True 
     raise PermissionDenied({"message":"You don't have permission to access", 
           "object_id": obj.id}) 

e nessuna necessità di sovrascrivere recuperare metodo

class CustomViewSet(...): 
    model = Model 
    permission_classes = (CustomPerm,) 

 

+0

Nel frontend, c'è un pulsante che collega alla pagina di accesso richiesta, dire '/ obj/1/request_access', se ho solo passato obj.id nel messaggio, dovrei analizzare il messaggio per questo, posso aumentare PermissionDenied e passare i dati (che include obj.id)? – WBC

+0

Al momento il json contiene "messaggio". Puoi aggiungere un altro campo come "object_id": obj.id ad esso – timop

+0

@WBC risposta aggiornata, provalo –