python - Django Rest Framework - return list of Users or single User with ModelViewSet based on Permissions -


i have seen several posts similar question, none solve issue.

i using django rest framework's modelviewset. have 2 views, detail view , list view.

i want if superuser accesses list view, gets users. if normal user accesses list view, can see himself.

if superuser accesses detail view, can view user. if normal user accesses detail view not his, gets authentication error.

i first attempted permissions only, realized query set of list view has_object_permission not run allowing authenticated non-superuser view everyone. because object permissions run command. attempted override get_object, get_object not called list view made no difference. tried override get_quertyset without get_objects, broke detail view.

what understand get_object called first detail view, calls get_queryset if don't override either of them. if override get_queryset, breaks normal functionality of detail view , get_object (it doesn't filter based on primary key). there must more going on behind scenes see. there must way write get_queryset fix normal django version i'm not doing.

so below implemented works, don't understand why have override get_object. if override get_queryset, detail view broken , returns users when logged in superuser instead of 1 user filtered based on primary key. there way override get_queryset without get_object fix behavior?

views:

class userviewset(viewsets.modelviewset):     queryset = user.objects.all()     serializer_class = userserializer     permission_classes = (allowpostanyreadauthenticateduser,)      def get_queryset(self):         user = self.request.user         if user.is_superuser:             return user.objects.all()         return user.objects.filter(username=user.username)      def get_object(self):         obj = get_object_or_404(user.objects.filter(id=self.kwargs["pk"]))         self.check_object_permissions(self.request, obj)         return obj 

permissions:

class allowpostanyreadauthenticateduser(permissions.basepermission):      def has_permission(self, request, view):         # allow register         if request.method == "post":             return true         # must authenticated view         else:             return request.user , is_authenticated(request.user)      def has_object_permission(self, request, view, obj):         # view method requires user         return obj.id == request.user.id or request.user.is_superuser 

serializer:

class userserializer(serializers.modelserializer):     class meta:         model = user         fields = ('username', 'email', 'id', 'password')         read_only_fields = ('id',)         extra_kwargs = {             'password': {'write_only': true}         } 

urls:

userlist = views.userviewset.as_view({     'get': 'list',     'post': 'create' })  userdetail = views.userviewset.as_view({     'get': 'retrieve',     'put': 'update',     'patch': 'partial_update',     'delete': 'destroy' })  urlpatterns = [     url(r'^$', userlist, name='users'),     url(r'^(?p<pk>\d+)$', userdetail, name='user'), ] 

you doing correctly! not need override get_object method on view though, modelviewset checks permissions in get_object.


Comments

Popular posts from this blog

php - Vagrant up error - Uncaught Reflection Exception: Class DOMDocument does not exist -

vue.js - Create hooks for automated testing -

Add new key value to json node in java -