I want users to be able to update only one specific field. For example:
models.py
class Snippet(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    title = models.CharField(max_length=100, blank=True, default='')
    code = models.TextField()
    linenos = models.BooleanField(default=False)
    language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100)
    style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100)
    class Meta:
        ordering = ('created',)
serializer.py
class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Snippet
        fields = ('id', 'title', 'code', 'linenos', 'language', 'style')
views.py
class SnippetList(generics.ListCreateAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
Once the Snippet is created, the user should only be able to update title field.
I know I can achieve that by something like this:
serializers.py
def update(self, instance, validated_data):
        """
        Update and return an existing `Snippet` instance, given the validated data.
        """
        instance.title = validated_data.get('title', instance.title)
        instance.save()
        return instance
In serializer class. But I want to know, is there a way that browsable API show only title field in edit form? And also skip validation for fields that are not required?
The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field instead of a primary key field.
Django REST Framework provides the read_only and write_only attributes for controlling what is used for editing and what is not.
class SnippetSerializer(serializers.ModelSerializer):
    class Meta:
        model = Snippet
        fields = ('id', 'title', 'code', 'linenos', 'language', 'style')
        extra_kwargs = {
            'id': {'read_only': True},
            'code': {'read_only': True},
            'lineos': {'read_only': True},
            'language': {'read_only': True},
            'style': {'read_only': True}
        }
The above will return all the fields on read requests but only title will be writable. You can find more at the official documentation: http://www.django-rest-framework.org/api-guide/serializers/#specifying-read-only-fields
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With