Search code examples
pythondjangopermissionsdjango-rest-frameworkdjango-permissions

Django Permissions: How to make extended User only to update and view profile?


I'm trying to write custom permissions for the extended user which I created so that it should only be allowed to see(retrieve) the user profile and update it. However with my current code, it is not allowing User to see it's profile. I've just started with Django and not able to come up with a solution, so please advise what is wrong? Below is my code:

Permissions.py

from rest_framework import permissions


class UserPermissions(permissions.BasePermission):

    def has_permission(self, request, view):
        return request.user and request.user.is_authenticated()

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

views.py

from rest_framework.permissions import IsAuthenticated, IsAdminUser
from .permissions import UserPermissions


class UserList(generics.ListCreateAPIView):

    queryset = UserProfile.objects.all()
    model = UserProfile
    serializer_class = UserSerializer
    paginate_by = 10
    permission_classes = (IsAuthenticated, IsAdminUser,)

    def get_queryset(self):

        queryset = UserProfile.objects.all()
        search_query = self.request.query_params.get('user', None)

        if search_query is not None:
            queryset = queryset.filter(username__istartswith=search_query)
        queryset = queryset.order_by('username')
        return queryset


class UserDetail(generics.RetrieveUpdateAPIView):

    queryset = UserProfile.objects.all()
    model = UserProfile
    serializer_class = UserSerializer
    permission_classes = (IsAuthenticated, UserPermissions,)


class UserDelete(generics.DestroyAPIView):

    queryset = UserProfile.objects.all()
    model = UserProfile
    serializer_class = UserSerializer
    permission_classes = (IsAuthenticated, IsAdminUser,)

Serializers.py

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = UserProfile

    def create(self, validated_data):

        user = super(UserSerializer, self).create(validated_data)
        user.set_password(validated_data['password'])
        user.save()
        return user

models.py

from django.contrib.auth.models import User

class UserProfile(User):

    class Meta:

        ordering = ["username"]
        db_table = 'user'

    createdby = models.CharField(max_length=100, blank=True, default="")
    updatedon = models.DateTimeField(blank=True, auto_now=True)
    is_admin = models.BooleanField(default=False)

Solution

  • because UserProfile != User, :

    class UserPermissions(permissions.BasePermission):
    
        def has_object_permission(self, request, view, obj):
            # obj is UserProfile instance not User instance.
            # so, this method will always return False
            return obj == request.user
    

    others code contains UserProfile are wrong too. about extend User you can follow the document: https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#extending-user https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#auth-custom-user