python-Django rest框架序列化多对多字段

如何将多对多字段序列化为列表,然后通过rest框架返回它们? 在下面的示例中,我尝试返回该帖子以及与其关联的标签列表。

models.py

class post(models.Model):
    tag = models.ManyToManyField(Tag)
    text = models.CharField(max_length=100)

serializers.py

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ("text", "tag"??)

views.py

class PostViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
6个解决方案
69 votes

您将需要TagSerializer,其class Meta具有model = Tag。在创建TagSerializer之后,将PostSerializer修改为many=True,以实现ManyToManyField关系:

class PostSerializer(serializers.ModelSerializer):
    tag = TagSerializer(read_only=True, many=True)

    class Meta:
        ...

答案是针对DRF 3

Brian answered 2019-11-08T09:15:52Z
14 votes

这就是我所做的,假设一本书可以有多个作者,而一个作者可以有多个本书:在模型上:

class Author(models.Model):
    name = models.CharField(max_length=100, default="")
    last_name = models.IntegerField(default=0)

class Book(models.Model):
    authors = models.ManyToManyField(Author, related_name="book_list", blank=True)
    name = models.CharField(max_length=100, default="")
    published = models.BooleanField(default=True)

在序列化器上:

class BookSerializer(serializers.ModelSerializer):
    authors = serializers.PrimaryKeyRelatedField(queryset=Author.objects.all(), many=True)

    class Meta:
        model = Book
        fields = ('id', 'name', 'published', 'authors')


class AuthorSerializer(serializers.ModelSerializer):
    book_list = BookSerializer(many=True, read_only=True)

    class Meta:
        model = Author
        fields = ('id', 'name', 'last_name', 'book_list')
Jesus Almaral answered 2019-11-08T09:16:26Z
3 votes

Django 2.0

对于多对多领域,如果要特定领域:

class QuestionSerializer(serializers.ModelSerializer):

    topics_list = serializers.SerializerMethodField()

    def get_topics_list(self, instance):
        names = []
        a = instance.topics.get_queryset()
        for i in a:
            names.append(i.desc)
        return names
    class Meta:
        model = Question
        fields = ('topics_list',)
user5299374 answered 2019-11-08T09:16:59Z
2 votes

在init方法的序列化器中,您可以将queryset传递给字段,并且rest_framework验证该queryset上的ID

1)首先从serializers.ModelSerializer扩展您的序列化器

class YourSerializer(serializers.ModelSerializer):

2)在meta类上包含字段

class YourSerializer(serializers.ModelSerializer):
  class Meta:
        fields = (..., 'your_field',)

3)在init方法中:

def __init__(self, *args, **kwargs):
    super(YourSerializer, self).__init__(*args, **kwargs)
    self.fields['your_field].queryset = <the queryset of your field>

您可以像平常一样使用filter来限制该字段的查询集在任何参数下,也可以排除在外。 如果要包含所有内容,只需使用.objects.all()

yiyo answered 2019-11-08T09:17:51Z
1 votes

这适合我。

tag = TagSerializer(source="tag", read_only=True, many=True)
Windsooon answered 2019-11-08T09:18:14Z
1 votes

添加到@Brian的答案“ tags”:[{“ name”:“ tag1”}]可以简化为“ tags”:[“ tag1”,“ tag2”,...]:

class PostSerializer(serializers.ModelSerializer):
    tag = TagSerializer(read_only=True, many=True)

    class Meta:
        ...

class TagSerializer(serializers.RelatedField):

     def to_representation(self, value):
         return value.name

     class Meta:
        model = Tag

此处提供更多信息:[https://www.django-rest-framework.org/api-guide/relations/#custom-relational-fields]

candyfoxxx answered 2019-11-08T09:18:48Z
translate from https://stackoverflow.com:/questions/33182092/django-rest-framework-serializing-many-to-many-field