简体   繁体   中英

Cannot serialize AnonymousUser object using Django Rest Framework - missing attributes

I am trying to make available the current user object so my AJAX front-end can determine if the user is logged in or not.

The current user is either an instance of dajngo.contrib.auth.User for logged in people or AnonymousUser for non-logged in people. The serializer is as follows,

class UserSerializer(serializers.HyperlinkedModelSerializer):
    comments = serializers.HyperlinkedRelatedField(many = True, view_name = 'comment-detail')
    class Meta:
        model = User
        fields = ('url', 'username', 'comments', 'first_name', 'last_name')

with the following view

class CurrentUserView(APIView):
    '''
    Returns the current user, logged in or not
    '''
    def get(self, request, *args, **kwargs):
        serializer = serializers.UserSerializer(request.user)
        return Response(serializer.data)

This serializer works fine for logged in users ie it patches on the 'comments' field and sends it off. However for AnonymousUser it chokes. It claims that there is no method 'comments' (which there isn't but it should be patched on right?) and if I remove the 'comments' requirement from fields it then complains about no 'first_name'.

Is this an issue with AnonymousUser not being an instance of django.contrib.auth.User ? If so, how do I remedy it?

I realise I could check at the View level and return a custom data object if it is an instance of AnonymousUser but is there a neater way to do this?

It's better to serialize like this, moving authentication check to backend (where it belongs):

{
    'is_logged_in': True,
    'user': <<serialized user>>,
}

and:

{
    'is_logged_in': False,
    'user': None, # or something else like this
}

It's common solution in many APIs. Metadata is on top of JSON and possible objects under a key(s). You can check if user is AnonymousUser or User by checking .is_authenticated() - it's been specially created for such purpose (compare with: AnonymousUser ).

Modify your view like shown below

class CurrentUserView(APIView):
    '''
    Returns the current user, logged in or not
    '''
    def get(self, request, *args, **kwargs):
        if request.user.is_authenticated():
            serializer = serializers.UserSerializer(request.user)
            return Response(serializer.data)
        else:
            return Response([])`

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM