Wie serialisiere ich ein Viele-zu-Viele-Feld in eine Liste von etwas und gebe sie über das Rest-Framework zurück? In meinem Beispiel unten versuche ich, den Beitrag zusammen mit einer Liste der damit verbundenen 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
Antworten:
Sie benötigen eine
TagSerializer
, derenclass Meta
hatmodel = Tag
. NachTagSerializer
erstellt wird, ändern diePostSerializer
mitmany=True
für eineManyToManyField
Beziehung:class PostSerializer(serializers.ModelSerializer): tag = TagSerializer(read_only=True, many=True) class Meta: model = Post fields = ('tag', 'text',)
Die Antwort ist für DRF 3
quelle
read_only=True
Teil wird hier erklärt: django-rest-framework.org/api-guide/relations/…Nehmen wir an, ein Buch kann mehr als einen Autor haben und ein Autor kann mehr als ein Buch haben: 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)
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')
quelle
Das Hinzufügen zu @ Brians Antwort "tags": [{"name": "tag1"}] kann auf folgende Weise zu "tags": ["tag1", "tag2", ...] vereinfacht werden:
class PostSerializer(serializers.ModelSerializer): tag = TagSerializer(read_only=True, many=True) class Meta: ... class TagSerializer(serializers.RelatedField): def to_representation(self, value): return value.name class Meta: model = Tag
Weitere Informationen hier: https://www.django-rest-framework.org/api-guide/relations/#custom-relational-fields
quelle
Django 2.0
Für viele bis viele Bereiche, wenn Sie einen bestimmten möchten:
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',)
quelle
get_topics_list
Sie könnten vereinfachen, umreturn list(instance.topics.values_list('desc', flat=True))
Das funktioniert bei mir.
tag = TagSerializer(source="tag", read_only=True, many=True)
quelle
In der Methode serializer on init können Sie das Abfrageset an das Feld übergeben und rest_framework die IDs auf diesem Abfrageset validieren
1) Erweitern Sie zuerst Ihren Serializer von Serializers.ModelSerializer
class YourSerializer(serializers.ModelSerializer):
2) Fügen 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 den Abfragesatz für dieses Feld unter einem beliebigen Argument mithilfe von Filter einschränken oder ausschließen, wie Sie es normalerweise tun. Wenn Sie alle einschließen möchten, verwenden Sie einfach .objects.all ()
quelle
Die Standardeinstellung
ModelSerializer
verwendet Primärschlüssel für Beziehungen. Mit demMeta
depth
Attribut können Sie jedoch problemlos verschachtelte Darstellungen erstellen:class PostSerializer(serializers.ModelSerializer): class Meta: model = Post fields = ("text", "tag") depth = 1
Wie in der Dokumentation erwähnt :
quelle