Django休息框架序列化很多到很多领域

ken*_*gcc 58 python django django-models django-serializer django-rest-framework

如何将多对多字段序列化为某些列表,并通过休息框架返回它们?在下面的示例中,我尝试将帖子与一个与之关联的标签列表一起返回.

models.py

class post(models.Model):
    tag = models.ManyToManyField(Tag)
    text = models.CharField(max_length=100)
Run Code Online (Sandbox Code Playgroud)

serializers.py

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ("text", "tag"??)
Run Code Online (Sandbox Code Playgroud)

views.py

class PostViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
Run Code Online (Sandbox Code Playgroud)

Bri*_*ian 72

你需要一个TagSerializer,class Meta有的model = Tag.之后TagSerializer被创建,修改PostSerializermany=True一个ManyToManyField关系:

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

    class Meta:
        ...
Run Code Online (Sandbox Code Playgroud)

答案是DRF 3

  • 如果您希望能够通过 Post 更新标签怎么办?(例如不是 read_only)当我拿走 read_only 并尝试修补标签字段的更新时,我得到了奇怪的行为(我收到关于标签已经存在的错误) (4认同)
  • 现在,我得到: "tags": [{"name": "tag1"}] 我想将其简化为: "tags": ["tag1", "tag2",...] (2认同)
  • `read_only=True` 部分解释如下:http://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers (2认同)

Jes*_*ral 14

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

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)
Run Code Online (Sandbox Code Playgroud)

在序列化器上:

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')
Run Code Online (Sandbox Code Playgroud)

  • 是的,必须在Views类上完成,如果您需要更详细的答案,请发布另一个问题 (2认同)

小智 11

添加到@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
Run Code Online (Sandbox Code Playgroud)

更多信息:https : //www.django-rest-framework.org/api-guide/relations/#custom-relational-fields


小智 7

默认ModelSerializer使用主键作为关系。但是,您可以使用以下Meta depth属性轻松生成嵌套表示:

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ("text", "tag")
        depth = 1 
Run Code Online (Sandbox Code Playgroud)

文档中所述:

depth选项应设置为整数值,该值指示在恢复为平面表示之前应遍历的关系深度。


Win*_*oon 5

这对我有用。

tag = TagSerializer(source="tag", read_only=True, many=True)
Run Code Online (Sandbox Code Playgroud)