wake-up-neo.com

Django Rest Framework, das viele zu vielen Feldern serialisiert

Wie kann ich ein Many-to-Many-Feld in eine Liste von etwas serialisieren und durch Rest-Framework zurückgeben? In meinem Beispiel versuche ich, den Beitrag zusammen mit einer Liste der damit verknüpften Tags zurückzugeben.

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

Sie benötigen eine TagSerializer, deren class Metamodel = Tag hat. Nachdem TagSerializer erstellt wurde, ändern Sie PostSerializer mit many=True für eine ManyToManyField-Beziehung:

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

    class Meta:
        ...

Antwort ist für DRF 3

49
Brian

So habe ich es gemacht, nehmen wir an, ein Buch kann mehr als einen Autor haben und ein Autor kann mehr als ein Buch haben:

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)

Auf Serialisierern:

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

Im Serializer der init - Methode können Sie das Abfrageset an das Feld übergeben und rest_framework die IDs dieses Abfragesets bestätigen

1) Erweitern Sie zunächst Ihren Serialisierer von Serialisierern.ModelSerializer

class YourSerializer(serializers.ModelSerializer):

2) schließen Sie das Feld in die Metaklasse ein

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

3) in der init-Methode:

def __init__(self, *args, **kwargs):
    super(YourSerializer, self).__init__(*args, **kwargs)
    self.fields['your_field].queryset = <the queryset of your field>

Sie können das Abfrageset für dieses Feld mit einem beliebigen Argument mithilfe von filter einschränken oder wie üblich ausschließen. Wenn Sie alle einschließen möchten, verwenden Sie einfach .objects.all ().

2
yiyo

Django 2.0

Für viele bis viele Felder, wenn Sie ein bestimmtes Feld wünschen:

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

Das funktioniert für mich.

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