Saša Kalaba
Saša Kalaba

Reputation: 4411

Django Rest Framework setting default PrimaryKeyRelated field value?

Django 1.7

DRF 3.3.2

Python 2.7

In my API I want to set a default value for the user field. For example I have a Playlist model and I want to make sure that on create and update the user is always set from request.user.

My first idea was to override the update method in my views, something like this:

views.py

class PlaylistViewSet(viewsets.ModelViewSet):
    serializer_class = PlaylistSerializer
    lookup_field = 'id'

    def update(self, request, *args, **kwargs):
        request.POST._mutable = True
        request.POST['user'] = request.user.id
        request.POST._mutable = False
        return super(PlaylistViewSet, self).update(request, *args, **kwargs)

This just overrides any POST data for values that I want to be always set. However this feels hacky and I believe there's a better way.

Second solution:

I pass user with my get_serializer method:

views.py

class PlaylistViewSet(viewsets.ModelViewSet):
    serializer_class = PlaylistSerializer
    lookup_field = 'id'

    def get_serializer(self, *args, **kwargs):
        kwargs['user'] = self.request.user
        return super(PlaylistViewSet, self).get_serializer(*args, **kwargs)

and then I can access it from the serializer init method:

serializers.py

class PlaylistSerializer(serializers.ModelSerializer):
    user = PrimaryKeyRelatedField(allow_null=True, queryset=User.objects.all(), required=False)    
    class Meta:
        model = Playlist

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user')
        # set the value of the user field here
        super(PlaylistSerializer, self).__init__(*args, **kwargs)

And this is where I'm stuck. I can't seem to figure out how to set a value for a PrimaryKeyRelated Field.

I access the field with:

self.fields['owner']

but I can't access its data or set pk value.

Upvotes: 1

Views: 2015

Answers (1)

ilse2005
ilse2005

Reputation: 11429

The easiest way to achieve what you want is to override the perform_create and perform_update methods of your PlaylistViewSet (Save and deletion hooks)

class PlaylistViewSet(viewsets.ModelViewSet):
    serializer_class = PlaylistSerializer
    lookup_field = 'id'

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

    def perform_update(self, serializer):
        serializer.save(user=self.request.user)

Upvotes: 4

Related Questions