Django rest framework serializing many to many fie

2019-01-16 18:24发布

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.

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条回答
Viruses.
2楼-- · 2019-01-16 18:31

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:

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

    class Meta:
        ...

Answer is for DRF 3

查看更多
Melony?
3楼-- · 2019-01-16 18:32

In the serializer on init method you can pass the queryset to the field and rest_framework valide the ids on that queryset

1) first extend your serializer from serializers.ModelSerializer

class YourSerializer(serializers.ModelSerializer):

2) include the field on the meta class

class YourSerializer(serializers.ModelSerializer):
  class Meta:
        fields = (..., 'your_field',)

3) in the init method:

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

查看更多
叛逆
4楼-- · 2019-01-16 18:39

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',)
查看更多
爱情/是我丢掉的垃圾
5楼-- · 2019-01-16 18:49

This works for me.

tag = TagSerializer(source="tag", read_only=True, many=True)
查看更多
啃猪蹄的小仙女
6楼-- · 2019-01-16 18:52

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:

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')
查看更多
登录 后发表回答