1

I'm trying to implement a user profile in django rest framework.

Users should be able to request the profile of other users; however, since profiles contain sensitive information, I want to limit the information returned to non-owners and non-authenticated users when they request a profile.

I'm looking for a test that I can run inside my view methods that will determine which serializer to use for that request.

How can I do this?

# models.py
class Profile(models.Model):

    user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='profile')
    bio = models.CharField(max_length=100)
    # dob is sensitive and should be protected...
    dob = models.DateTimeField(blank=True, null=True)

My serializers would look like this:

# serializers.py
# Only for the owner...
class ProfileOwnerSerializer(serializers.HyperlinkedModelSerializer):
    user = serializers.ReadOnlyField(source='user.id')
    first_name = serializers.ReadOnlyField(source='user.first_name')
    last_name = serializers.ReadOnlyField(source='user.last_name')

    class Meta:
        model = Profile
        fields = (
            'url',
            'id',
            'dob',     #sensitive
            'user',
            'first_name',
            'last_name',   #sensitive
        )

#For logged in users...
class ProfileSerializer(serializers.HyperlinkedModelSerializer):
    user = serializers.ReadOnlyField(source='user.id')
    first_name = serializers.ReadOnlyField(source='user.first_name')

    class Meta:
        model = Profile
        fields = (
            'url',
            'id',
            'bio',
            'user',
            'first_name',
        )

#For everyone else...
class NonAuthProfileSerializer:
    ...

And I would try to distinguish between them here...

# views.py
class ProfileDetail(APIView):
    """
    Retrieve a profile instance.
    """

    # Can't user permission_classes bc I want to cater to different classes...

    def get_object(self, pk):
        try:
            return Profile.objects.get(pk=pk)
        except Profile.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        profile = self.get_object(pk)
        # is_owner = ???
        # is_authenticated = ???

        # Define the serializer to be ProfileSerializer, ProfileOwnerSerializer, etc.
        serializer = CorrectSerializer(
            profile,
            context={"request": request},
        )
        return Response(serializer.data)

I don't think it'd be too hard to check if the request was sent by the owner, since I can just cross-reference the profile id.

However, how would I check whether the user was logged in or not? I've tried looking at request.user.auth in the view method, but that seems to be None whether or not the request is logged in.

4

1 回答 1

1

I think you should be checking with request.user.is_authenticated(). To fill in the blanks:

is_owner = profile.user == request.user
is_authenticated = request.user.is_authenticated()
于 2017-06-21T23:09:59.597 回答