Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest Framework Serializers: exclude from validation related entity

I have m2m related entities:

class Tag(models.Model):
    name = models.CharField(
       max_length=80,
       blank=False,
       unique=True
)

class File(models.Model):
    tags = models.ManyToManyField(Tag)
    uploader = models.ForeignKey(User, on_delete=models.DO_NOTHING)

    name = models.CharField(
        max_length=255,
        blank=False,
        unique=True,
    )

and serializers for them:

class TagSerializer(serializers.ModelSerializer):
    class Meta:
        model = Tag
        fields = ('id', 'name')
        extra_kwargs = {
            'name': {
                'validators': [],
            },
        }

class FileSerializer(serializers.ModelSerializer):
    tags = TagSerializer(many=True, read_only=False)

    class Meta:
        model = File
        fields = ('id', 'name', 'tags')

    def update(self, instance, validated_data):
        tags_data = validated_data.pop('tags')

        if 'name' in validated_data:
           instance.name = validated_data['name']


        instance_tags = instance.tags.all()
        new_tag_list = []

        # add new tags
        for tag in tags_data:
            tag, created = Tag.objects.get_or_create(name=tag['name'])
            new_tag_list.append(tag)
            if tag not in instance_tags:
                instance.tags.add(tag)

        # remove old tags
        for instance_tag in instance_tags:
            if instance_tag not in new_tag_list:
                instance.tags.remove(instance_tag)

        return instance

as you can see I turned off all validation for Tag.name field in TagSerializer by this code setting: extra_kwargs = {'name': {'validators': []}} This is because of validation errors during saving updated File:

serializer = FileSerializer(file, data=request.data, partial=True)
if serializer.is_valid(): 
    ...

If you have File with list of tags and just want to add or remove some tags, you'll have error 'tag with such name already exists'.

So this spike is working, but for now I don't have unique check for Tag.name. I tried to write something like what in FileSerializer:

class FileSerializer(serializers.ModelSerializer):
    class Meta:
       model = File
       extra_kwargs = {
           'tags': {
                'validators': [],
            },
        }

but of course it's not working. Question is about any possibilities to not validate Tag entities at all when I add/remove its bindings with file.

like image 545
40min Avatar asked Oct 18 '25 00:10

40min


1 Answers

You can try, this way for update, but if this solution correct for you, you need also override the create method.

class FileSerializer(serializers.ModelSerializer):
    tags = TagSerializer(many=True, read_only=True)
    #                                       ^^^^^^

    class Meta:
        model = File
        fields = ('id', 'name', 'tags')

    def update(self, instance, validated_data):
        # Override tags_data = validated_data.pop('tags')
        # this way
        request = self.context['request']
        tags_data = request.data.get('tags', [])

        # Next your current code

in serializer initial add extra-context , when you use views from drf context added by get_serializer method.

serializer = FileSerializer(file, data=request.data, partial=True, context={'request': request})

Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!