Comment puis-je sérialiser un champ plusieurs-à-plusieurs dans une liste de quelque chose et les renvoyer dans un cadre de repos? Dans mon exemple ci-dessous, j'essaie de renvoyer l'article avec une liste de balises qui lui sont associées.
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
Vous aurez besoin d'une TagSerializer
, dont class Meta
a model = Tag
. Une fois que TagSerializer
est créé, modifiez la PostSerializer
avec many=True
pour une relation ManyToManyField
:
class PostSerializer(serializers.ModelSerializer):
tag = TagSerializer(read_only=True, many=True)
class Meta:
...
C’est ce que j’ai fait, supposons qu’un livre puisse avoir plus d’un auteur et qu’un auteur puisse avoir plus d’un livre: Sur modèle:
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)
Sur les sérialiseurs:
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')
Dans le sérialiseur sur la méthode init vous pouvez passer le queryset au champ et rest_framework valider les id
1) d’abord étendre votre sérialiseur à partir de sérialiseurs.ModelSerializer
class YourSerializer(serializers.ModelSerializer):
2) inclure le champ sur la méta-classe
class YourSerializer(serializers.ModelSerializer):
class Meta:
fields = (..., 'your_field',)
3) dans la méthode init:
def __init__(self, *args, **kwargs):
super(YourSerializer, self).__init__(*args, **kwargs)
self.fields['your_field].queryset = <the queryset of your field>
Vous pouvez limiter le queryset pour ce champ sous n’importe quel argument en utilisant un filtre ou une exclusion, comme vous le faites normalement. Si vous souhaitez tout inclure, utilisez simplement .objects.all ()
Django 2.0
Pour plusieurs champs, si vous en voulez un spécifique:
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',)
Cela fonctionne pour moi.
tag = TagSerializer(source="tag", read_only=True, many=True)