Python Django rest框架序列化多对多字段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33182092/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Django rest framework serializing many to many field
提问by kengcc
How do I serialize a many-to-many field into list of something, and return them through rest framework? In my example below, I try to return the post together with a list of tags associated with it.
如何将多对多字段序列化为列表,并通过rest框架返回它们?在下面的示例中,我尝试将帖子连同与其关联的标签列表一起返回。
models.py
模型.py
class post(models.Model):
tag = models.ManyToManyField(Tag)
text = models.CharField(max_length=100)
serializers.py
序列化程序.py
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ("text", "tag"??)
views.py
视图.py
class PostViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
采纳答案by Brian
You will need a TagSerializer
, whose class Meta
has model = Tag
. After TagSerializer
is created, modify the PostSerializer
with many=True
for a ManyToManyField
relation:
您将需要一个TagSerializer
,其class Meta
具有model = Tag
。之后TagSerializer
被创建,修改PostSerializer
与many=True
一个ManyToManyField
关系:
class PostSerializer(serializers.ModelSerializer):
tag = TagSerializer(read_only=True, many=True)
class Meta:
model = Post
fields = (tag, text,)
回答by Windsooon
This works for me.
这对我有用。
tag = TagSerializer(source="tag", read_only=True, many=True)
回答by yiyo
In the serializer on initmethod you can pass the queryset to the field and rest_framework valide the ids on that queryset
在init方法的序列化程序中,您可以将查询集传递给字段,然后 rest_framework 验证该查询集上的 id
1) first extend your serializer from serializers.ModelSerializer
1)首先从 serializers.ModelSerializer 扩展你的序列化器
class YourSerializer(serializers.ModelSerializer):
2) include the field on the meta class
2) 在元类中包含字段
class YourSerializer(serializers.ModelSerializer):
class Meta:
fields = (..., 'your_field',)
3) in the init method:
3)在init方法中:
def __init__(self, *args, **kwargs):
super(YourSerializer, self).__init__(*args, **kwargs)
self.fields['your_field].queryset = <the queryset of your field>
You can limit the queryset for that field under any argument using filter or exclude like normally you do. In case that you want include all just use .objects.all()
您可以像往常一样使用 filter 或 exclude 限制任何参数下该字段的查询集。如果您想包含所有内容,请使用 .objects.all()
回答by user5299374
Django 2.0
Django 2.0
For many to many field, if you want specific one:
对于多对多领域,如果你想要特定的一个:
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',)
回答by Jesus Almaral - Hackaprende
This is what I did, let′s suppose a Book can have more than one author and an Author can have more than one book: On Model:
这就是我所做的,假设一本书可以有多个作者,而一个作者可以有多个书: On Model:
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)
On Serializers:
在序列化器上:
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')
回答by candyfoxxx
Adding to @Brian's answer "tags": [{"name": "tag1"}] can be simplified to "tags": ["tag1", "tag2",...] in this way:
添加到@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
More info here: https://www.django-rest-framework.org/api-guide/relations/#custom-relational-fields
更多信息:https: //www.django-rest-framework.org/api-guide/relations/#custom-relational-fields
回答by mohamed ali Mimouni
The default ModelSerializer
uses primary keys for relationships. However, you can easily generate nested representations using the Meta
depth
attribute:
默认ModelSerializer
使用主键作为关系。但是,您可以使用以下Meta
depth
属性轻松生成嵌套表示:
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ("text", "tag")
depth = 1
As mentioned in the documentation:
如文档中所述:
The
depth
option should be set to an integer value that indicates the depth of relationships that should be traversed before reverting to a flat representation.
该
depth
选项应设置为整数值,该值指示在恢复为平面表示之前应遍历的关系深度。