2014-05-18 26 views
6

Mi stavo chiedendo le migliori pratiche quando si tratta di Django Rest Framework. Ho limitato l'accesso alla modifica di determinati attributi su un account tramite l'utilizzo di diversi serializzatori per utente (personale vs proprietario dell'account rispetto a chiunque altro) e il metodo HTTP, ma mi sembra che questo sia troppo antipolitico.Django Rest Framework: migliori pratiche?

È questo il modo migliore per eseguire il mio compito di separare le "autorizzazioni" per modificare diversi campi di un oggetto? O c'è un modo migliore e più pitonico per realizzare ciò che sto facendo in questo modo al momento?

Qualsiasi e tutte le critiche con il seguente codice sono accettate, in quanto ritengo di aver tagliato qualche angolo.

Grazie mille.

from rest_framework import serializers, viewsets 
from rest_framework.permissions import SAFE_METHODS 
from accounts.models import User 
from cpapi.permissions import * 


class UserSerializer(serializers.HyperlinkedModelSerializer): 
    class Meta: 
     model = User 
     fields = ('id', 'url', 'username', 'password') 
     write_only_fields = ('password',) 

    def restore_object(self, attrs, instance=None): 
     user = super(UserSerializer, self).restore_object(attrs, instance) 
     if 'password' in attrs.keys(): 
      user.set_password(attrs['password']) 
     return user 

class UserDetailsSerializer(UserSerializer): 
    class Meta(UserSerializer.Meta): 
     fields = ('id', 'url', 'username', 'password', 'email') 

class UserListSerializer(UserSerializer): 
    class Meta(UserSerializer.Meta): 
     fields = ('id', 'url', 'username') 

class UserWithoutNameSerializer(UserSerializer): 
    class Meta(UserSerializer.Meta): 
     fields = ('id', 'url', 'password', 'email') 


class UserViewSet(viewsets.ModelViewSet): 
    """ 
    API endpoint that allows users to be viewed or edited. 
    """ 
    serializer_class = UserSerializer 
    model = User 

    def get_serializer_class(self): # Modify to allow different information for different access (userlist vs staff) 
     serializer_class = self.serializer_class 
     if 'List' in self.get_view_name(): 
      serializer_class = UserListSerializer 
     elif self.request.method in ['PUT', 'PATCH']: 
      serializer_class = UserWithoutNameSerializer 
     elif self.get_object() == self.request.user or self.request.user.is_staff: 
      serializer_class = UserDetailsSerializer 
     return serializer_class 

    def get_permissions(self): 
     if self.request.method in SAFE_METHODS or self.request.method == 'POST': 
      return [AllowAny()] 
     elif self.request.method == 'DELETE': 
      return [IsAdminUser()] 
     else: 
      return [IsStaffOrTargetUser()] 

risposta

1

Se ho capito bene quello che vuoi è di autorizzazioni per-campo, e non Django Django non-REST-quadro li supporta direttamente. È possibile installare un pacchetto come Django Fine-Grained Permissions ma si rimane bloccati con la stessa soluzione perché non c'è modo di comunicare tali autorizzazioni alla vista API REST.

Si consiglia di attenersi alla soluzione, o inserire la logica di selezione del serializzatore in un serializzatore che contiene tutti i campi e passare il ruolo al costruttore e consentire al serializzatore di creare un elenco di campi in base ad esso, ma per farlo funzionare dovresti scrivere la tua sottoclasse Serializer.