如何将多对多字段序列化为某些列表,并通过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
答案 0 :(得分:54)
您需要TagSerializer
,其class Meta
有model = Tag
。创建TagSerializer
后,使用PostSerializer
修改many=True
以获得ManyToManyField
关系:
class PostSerializer(serializers.ModelSerializer):
tag = TagSerializer(read_only=True, many=True)
class Meta:
...
答案 1 :(得分:6)
这就是我所做的,假设一本书可以有多个作者,而一个作者可以有多个本书: 在模型上:
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')
答案 2 :(得分:3)
添加到@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
答案 3 :(得分:2)
在 init 方法的序列化程序中,您可以将查询集传递给字段,rest_framework将该查询集上的ID保存为
1)首先从serializers.ModelSerializer
扩展序列化程序class YourSerializer(serializers.ModelSerializer):
2)在元类
中包含该字段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>
您可以使用过滤器或排除限制任何参数下该字段的查询集,就像通常那样。如果你想要包括所有只是使用.objects.all()
答案 4 :(得分:2)
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',)
答案 5 :(得分:1)
这适合我。
tag = TagSerializer(source="tag", read_only=True, many=True)
答案 6 :(得分:1)
默认的ModelSerializer
使用主键建立关系。但是,您可以使用Meta
depth
属性轻松生成嵌套表示:
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ("text", "tag")
depth = 1
如documentation中所述:
depth
选项应设置为整数值,该值指示在还原为平面表示形式之前应遍历的关系的深度。