web-dev-qa-db-fra.com

Cadre de repos Django sérialisant plusieurs champs

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
43
kengcc

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:
        ...

La réponse est pour DRF 3

49
Brian

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')
3
Jesus Almaral

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 ()

2
yiyo

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',)
2
user5299374

Cela fonctionne pour moi.

tag = TagSerializer(source="tag", read_only=True, many=True)
1
Windsooon