处理DRF序列化程序中的ManyToMany字段

时间:2017-10-24 11:05:31

标签: django django-rest-framework many-to-many serializer

我有以下Django模型:

class Article(models.Model):
  name = models.CharField(max_length=30, unique=True)
  tags = models.ManyToManyField(Tag)
  ...

class Tag(models.Model):
  name = models.CharField(max_length=30, unique=True)
  ...

我希望能够在通过POST请求创建文章时添加现有标签列表,即

{ 'name': 'My Org Name', 'tags': [1,2,3] }

其中[1,2,3]是标签ID列表。

我的序列化器看起来像这样:

class ArticleSerializer(serializers.ModelSerializer):
     tags = serializers.PrimaryKeyRelatedField(many=True, read_only=True, allow_null=True)

     class Meta:
        model = Article
        fields = ('name', 'tags', ...)

     def create(self, validated_data):      
        # in create I will add tags, i.e. article.add(tag)    
        return Article.objects.create_article(**validated_data)

但是我想做一些验证,以便我知道传入的标记ID属于现有的Tag实例。所以我尝试将下面的方法添加到我的序列化程序中。

def validate_tags(self, tags):
    if tags:
        for tag in tags:
            if not Tag.get(pk=tag):
                raise ValueError('Tag with id not found...')
    return tags

由于某些原因,未触发此验证方法。我试图找出处理文章添加标签的正确方法,任何建议都将受到高度赞赏。

1 个答案:

答案 0 :(得分:1)

由于您要从序列化程序 ModelSerializer 进行扩展,因此您无需明确指定标记'标记。而你无需验证它们。 DRF完成剩下的工作并根据Model关系创建字段和验证查询。

class ArticleSerializer(serializers.ModelSerializer):

    class Meta:
        model = Article
        fields = ('name', 'tags', ...)

    def create(self, validated_data):
        tags = validated_data.pop('tags')
        article = Article.objects.create(**validated_data)
        article.tags.add(*tags)
        return article