Nehmen wir an, wir haben folgendes Modell:
class Classroom(models.Model):
room_number = [....]
class Teacher(models.Model):
name = [...]
tenure = [...]
classroom = models.ForeignKey(Classroom)
Angenommen, statt ein Ergebnis wie das folgende mit der ManyRelatedPrimaryKeyField-Funktion zu erhalten:
{
"room_number": "42",
"teachers": [
27,
24,
7
]
},
lassen Sie es etwas zurückgeben, das die vollständige zugehörige Modelldarstellung enthält, wie:
{
"room_number": "42",
"teachers": [
{
'id':'27,
'name':'John',
'tenure':True
},
{
'id':'24,
'name':'Sally',
'tenure':False
},
]
},
Ist das möglich? Wenn das so ist, wie? Und ist das eine schlechte Idee?
Am einfachsten ist es, das Tiefenargument zu verwenden
class ClassroomSerializer(serializers.ModelSerializer):
class Meta:
model = Classroom
depth = 1
Dies schließt jedoch nur Beziehungen für Vorwärtsbeziehungen ein, was in diesem Fall nicht ganz der Fall ist, da das Lehrerfeld eine umgekehrte Beziehung ist.
Wenn Sie komplexere Anforderungen haben (z. B. umgekehrte Beziehungen einschließen, einige Felder verschachteln, andere jedoch nicht, oder nur eine bestimmte Teilmenge von Feldern verschachteln), können Sie Serialisierer verschachteln , z. B. ...
class TeacherSerializer(serializers.ModelSerializer):
class Meta:
model = Teacher
fields = ('id', 'name', 'tenure')
class ClassroomSerializer(serializers.ModelSerializer):
teachers = TeacherSerializer(source='teacher_set')
class Meta:
model = Classroom
Beachten Sie, dass wir das Argument source im Feld serializer verwenden, um das Attribut anzugeben, das als Quelle des Felds verwendet werden soll. Wir könnten das Argument source
löschen, indem wir stattdessen sicherstellen, dass das Attribut teachers
vorhanden ist, indem wir die Option related_name für Ihr Modell Teacher
verwenden, d. H. classroom = models.ForeignKey(Classroom, related_name='teachers')
Beachten Sie, dass verschachtelte Serialisierer derzeit keine Schreibvorgänge unterstützen. Für beschreibbare Darstellungen sollten Sie normale flache Darstellungen verwenden, z. B. pk oder Hyperlinks.
Vielen Dank @TomChristie !!! Sie haben mir sehr geholfen! Ich möchte das ein wenig aktualisieren (wegen eines Fehlers, auf den ich gestoßen bin)
class TeacherSerializer(serializers.ModelSerializer):
class Meta:
model = Teacher
fields = ('id', 'name', 'tenure')
class ClassroomSerializer(serializers.ModelSerializer):
teachers = TeacherSerializer(source='teacher_set', many=True)
class Meta:
model = Classroom
field = ("teachers",)
Dies kann auch mit einem handlichen Dandy Django erreicht werden, der als drf-flex-fields bezeichnet wird. Wir benutzen es und es ist ziemlich genial. Sie installieren es einfach pip install drf-flex-fields
, Lassen es durch Ihren Serializer laufen, fügen expandable_fields
Und Bingo hinzu (Beispiel unten). Außerdem können Sie tief verschachtelte Beziehungen mithilfe der Punktnotation angeben.
from rest_flex_fields import FlexFieldsModelSerializer
class ClassroomSerializer(FlexFieldsModelSerializer):
class Meta:
model = Model
fields = ("teacher_set",)
expandable_fields = {"teacher_set": (TeacherSerializer, {"source": "teacher_set"})}
Dann fügen Sie Ihrer URL ?expand=teacher_set
Hinzu und es wird eine erweiterte Antwort zurückgegeben. Hoffe, das hilft irgendwann jemandem. Prost!