Django REST框架验证slug字段。

时间:2021-01-11 07:37:57

I have defined a serializer like this:

我定义了这样的序列化器:

class ActivitySerializer(serializers.ModelSerializer):
      activity_project = serializers.SlugRelatedField(queryset=Project.objects.all(), slug_field='project_name')

activity_tags = serializers.SlugRelatedField(queryset=Tag.objects.all(), slug_field='tag_name', many=True)
class Meta:
    model = Activity
    fields = ('activity_name', 'activity_description', 'activity_status', 'activity_completion_percent', 'activity_due_date', 'activity_project', 'activity_tags',)

Now if I insert an activity_tag that does not exist in the database, I get a validation error"

现在,如果我插入一个在数据库中不存在的activity_tag,就会出现一个验证错误"

{
    "activity_tags": [
        "Object with tag_name=test does not exist."
    ]
}

I would like to create a validation method that adds the tag in the database if it does not exist. I have tried using the

我想创建一个验证方法,如果标签不存在,可以将其添加到数据库中。我试过用

def validate(self, attrs): 
    ....

method, but apparently for a slug field there is a method that is called before this one.

方法,但是显然对于蛞蝓域有一个方法在这个方法之前被调用。

Can someone point me to the right method I should use? Would this method be called in the corresponding view?

有人能指出我应该使用的正确方法吗?这个方法会在相应的视图中被调用吗?

1 个解决方案

#1


1  

I think you would need to create a nested serializer for this to work. This is totally untested and off the top of my head, but maybe something like this:

我认为您需要创建一个嵌套的序列化器来实现这一点。这是完全没有经过测试的,在我的头顶上,但也许像这样:

class ActivityTagFieldSerializer(serializer.ModelSerializer):
    tag_name = serializers.SlugField()
    class Meta:
        model = Tag
        fields = ('tag_name')

class ActivitySerializer(serializer.ModelSerializer):
    activity_tags = ActivityTagFieldSerializer(many=True)
    class Meta:
        model = Activity
        fields = ('activity_tags', 'activity_project', ...)

    def create(self, validated_data):
        tags = validated_data.pop('activity_tags')
        activity = Activity.objects.create(**validated_data)
        for tag in tags:
            try:
                tag_to_add = Tag.objects.get(**tag)
            except:
                tag_to_add = Tag.objects.create(**tag)
            activity.activity_tags.add(tag_to_add)
        return activity

Check the API guide for writable nested serializers

检查可写嵌套序列化器的API指南

#1


1  

I think you would need to create a nested serializer for this to work. This is totally untested and off the top of my head, but maybe something like this:

我认为您需要创建一个嵌套的序列化器来实现这一点。这是完全没有经过测试的,在我的头顶上,但也许像这样:

class ActivityTagFieldSerializer(serializer.ModelSerializer):
    tag_name = serializers.SlugField()
    class Meta:
        model = Tag
        fields = ('tag_name')

class ActivitySerializer(serializer.ModelSerializer):
    activity_tags = ActivityTagFieldSerializer(many=True)
    class Meta:
        model = Activity
        fields = ('activity_tags', 'activity_project', ...)

    def create(self, validated_data):
        tags = validated_data.pop('activity_tags')
        activity = Activity.objects.create(**validated_data)
        for tag in tags:
            try:
                tag_to_add = Tag.objects.get(**tag)
            except:
                tag_to_add = Tag.objects.create(**tag)
            activity.activity_tags.add(tag_to_add)
        return activity

Check the API guide for writable nested serializers

检查可写嵌套序列化器的API指南