2

I am having an issue in setting the user automatically in django rest framework. In my models.py I have the following:

Models.py

class Space(models.Model):
   creator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

Serializers.py

class SpaceSerializer(serializers.HyperlinkedModelSerializer):
    creator = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CreateOnlyDefault(serializers.CurrentUserDefault()))

    class Meta:
        model = Space
        fields = '__all__'

The intent is that the creator field will be set during creation through the API. When I issue a POST request to create the model, i get the following error:

"IntegrityError at /api/space/ NOT NULL constraint failed: apiapp_space.creator_id

I assume the serializer is not even using this field override, as when I set null=True in my model, it seems to save correctly with the creator field set to null.

Note that I have also tried using serializers.ModelSerializer.

How can I get django to recognize this field override?

aleksk
  • 661
  • 7
  • 15
  • what about removing `read_only=True`? – JPG Apr 19 '18 at 06:29
  • @JerinPeterGeorge This seems to have done the trick, but seems odd considering they actually recommend using this in the documentation - see http://www.django-rest-framework.org/api-guide/serializers/#specifying-read-only-fields also id rather not expose the field to the autogenerated API forms at all but I can live with it if I have to! – aleksk Apr 19 '18 at 06:37
  • Is it worked after removing `read_only=True`? – JPG Apr 19 '18 at 06:42
  • @JerinPeterGeorge yes it does. However, this allows other users to change this field if they want to, which is undesirable. – aleksk Apr 19 '18 at 06:44
  • @I posted one answer. Please give a try – JPG Apr 19 '18 at 06:57

1 Answers1

2

This is covered in the release notes for v3.8.

For read-only fields you need to pass the value when calling save:

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

The CreateOnlyDefault is used as the value for the unique_together validation on the model.

This was a breaking change in v3.8, required to allow correct behaviour elsewhere. (Previously read-only fields with a default were considered writable, with the default being used as the written value. Ultimately that turned out to be not a good idea.)

Carlton Gibson
  • 7,278
  • 2
  • 36
  • 46