Django rest framework сериализация многих ко многим поля

как сериализовать поле "многие ко многим" в список чего-то и вернуть их через REST framework? В моем примере ниже я пытаюсь вернуть сообщение вместе со списком тегов, связанных с ним.

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

5 ответов


вам понадобится TagSerializer, которого class Meta и model = Tag. После изменить на PostSerializer С many=True на ManyToManyField отношения:

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

    class Meta:
        ...

ответ для DRF 3


в сериализаторе on init метод вы можете передать queryset в поле и rest_framework valide идентификаторы на этом queryset

1) Сначала расширьте сериализатор из сериализаторов.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>

вы можете ограничить набор запросов для этого поля под любым аргументом с помощью фильтра или исключить, как обычно. В случае, если вы хочу включить все просто использовать .объекты.all ()


это то, что я сделал, предположим, что книга может иметь более одного автора, а автор может иметь более одной книги: На Модели:

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

это работает для меня.

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

Джанго 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',)