2013-01-12 2 views
5

A seguito di questo tutorial:quadro Django REST: aiutare il livello di oggetto permesso

http://django-rest-framework.org/tutorial/1-serialization.html

attraverso http://django-rest-framework.org/tutorial/4-authentication-and-permissions.html

ho questo codice:

# models.py 
class Message(BaseDate): 
    """ 
    Private Message Model 
    Handles private messages between users 
    """ 
    status = models.SmallIntegerField(_('status'), choices=choicify(MESSAGE_STATUS)) 
    from_user = models.ForeignKey(User, verbose_name=_('from'), related_name='messages_sent') 
    to_user = models.ForeignKey(User, verbose_name=_('to'), related_name='messages_received') 
    text = models.TextField(_('text')) 
    viewed_on = models.DateTimeField(_('viewed on'), blank=True, null=True) 


# serialisers.py 
class MessageSerializer(serializers.ModelSerializer): 
    from_user = serializers.Field(source='from_user.username') 
    to_user = serializers.Field(source='to_user.username') 

    class Meta: 
     model = Message 
     fields = ('id', 'status', 'from_user', 'to_user', 'text', 'viewed_on') 


# views.py 
from permissions import IsOwner 

class MessageDetail(generics.RetrieveUpdateDestroyAPIView): 
    model = Message 
    serializer_class = MessageSerializer 
    authentication_classes = (TokenAuthentication, SessionAuthentication) 
    permission_classes = (permissions.IsAuthenticated, IsOwner) 


# permissions.py 
class IsOwner(permissions.BasePermission): 
    """ 
    Custom permission to only allow owners of an object to edit or delete it. 
    """ 

    def has_permission(self, request, view, obj=None): 
     # Write permissions are only allowed to the owner of the snippet 
     return obj.from_user == request.user 


# urls.py 
urlpatterns = patterns('', 
    url(r'^messages/(?P<pk>[0-9]+)/$', MessageDetail.as_view(), name='api_message_detail'), 
) 

poi aprire l'URL delle API ho questo errore:

**AttributeError at /api/v1/messages/1/ 
'NoneType' object has no attribute 'from_user'** 

Traceback: 
File "/var/www/sharigo/python/lib/python2.6/site-packages/django/core/handlers/base.py" in get_response 
    111.       response = callback(request, *callback_args, **callback_kwargs) 
File "/var/www/sharigo/python/lib/python2.6/site-packages/django/views/generic/base.py" in view 
    48.    return self.dispatch(request, *args, **kwargs) 
File "/var/www/sharigo/python/lib/python2.6/site-packages/django/views/decorators/csrf.py" in wrapped_view 
    77.   return view_func(*args, **kwargs) 
File "/var/www/sharigo/python/lib/python2.6/site-packages/rest_framework/views.py" in dispatch 
    363.    response = self.handle_exception(exc) 
File "/var/www/sharigo/python/lib/python2.6/site-packages/rest_framework/views.py" in dispatch 
    351.    self.initial(request, *args, **kwargs) 
File "/var/www/sharigo/python/lib/python2.6/site-packages/rest_framework/views.py" in initial 
    287.   if not self.has_permission(request): 
File "/var/www/sharigo/python/lib/python2.6/site-packages/rest_framework/views.py" in has_permission 
    254.    if not permission.has_permission(request, self, obj): 
File "/var/www/sharigo/sharigo/apps/sociable/permissions.py" in has_permission 
    17.   return obj.from_user == request.user 

Exception Type: AttributeError at /api/v1/messages/1/ 
Exception Value: 'NoneType' object has no attribute 'from_user' 

Sembra che None venga passato come valore per il parametro "obj" a isOwner.has_permission(). Cosa sto sbagliando? Penso di aver seguito rigorosamente il tutorial.

+0

In DRF 3, non v'è 'has_object_permission' - http://www.django-rest-framework.org/api-guide/permessi/# permessi personalizzati –

risposta

9

Quando has_permission() viene chiamato con obj=None si suppone di restituire se l'utente ha il permesso di qualsiasi oggetto di questo tipo. Quindi dovresti gestire il caso quando viene passato None.

Il codice dovrebbe essere qualcosa del tipo:

def has_permission(self, request, view, obj=None): 
    # Write permissions are only allowed to the owner of the snippet 
    return obj is None or obj.from_user == request.user 
+0

dannazione, mi sono confuso perché all'inizio sembrava che il caso avesse fatto sì che la restrizione non funzionasse. Grazie. – nemesisdesign

9

Utilizzare la funzione has_object_permission invece di has_permission.

es:

def has_object_permission(self, request, view, obj=None): 
    return obj.from_user == request.user 

e chiamare la funzione check_object_permissions all'interno get_object in vista

def get_object(self): 
    obj = get_object_or_404(self.get_queryset()) 
    self.check_object_permissions(self.request, obj) 
    return obj