Ich habe eine Frage zum Umgang mit m2m / through-Modellen und deren Darstellung im Django Rest Framework. Nehmen wir ein klassisches Beispiel:
models.py:
from django.db import models
class Member(models.Model):
name = models.CharField(max_length = 20)
groups = models.ManyToManyField('Group', through = 'Membership')
class Group(models.Model):
name = models.CharField(max_length = 20)
class Membership(models.Model):
member = models.ForeignKey('Member')
group = models.ForeignKey('Group')
join_date = models.DateTimeField()
serializers.py:
imports...
class MemberSerializer(ModelSerializer):
class Meta:
model = Member
class GroupSerializer(ModelSerializer):
class Meta:
model = Group
views.py:
imports...
class MemberViewSet(ModelViewSet):
queryset = Member.objects.all()
serializer_class = MemberSerializer
class GroupViewSet(ModelViewSet):
queryset = Group.objects.all()
serializer_class = GroupSerializer
Wenn ich eine Instanz eines Mitglieds erhalte, erhalte ich erfolgreich alle Felder des Mitglieds und auch seine Gruppen. Ich erhalte jedoch nur die Gruppendetails, ohne zusätzliche Details, die aus dem Mitgliedschaftsmodell stammen.
Mit anderen Worten, ich erwarte Folgendes:
{
'id' : 2,
'name' : 'some member',
'groups' : [
{
'id' : 55,
'name' : 'group 1'
'join_date' : 34151564
},
{
'id' : 56,
'name' : 'group 2'
'join_date' : 11200299
}
]
}
Beachten Sie das join_date .
Ich habe so viele Lösungen ausprobiert, einschließlich natürlich der offiziellen Seite des Django Rest-Framework, und niemand scheint eine klare Antwort darauf zu geben - was muss ich tun, um diese zusätzlichen Felder einzuschließen? Ich fand es einfacher mit Django-Tastypie, hatte aber einige andere Probleme und bevorzuge Rest-Framework.
Antworten:
Wie wäre es mit.....
Definieren Sie in Ihrem MemberSerializer ein Feld wie folgt:
und dann können Sie auf Ihrem Mitgliedschafts-Serializer Folgendes erstellen:
Dies hat den Gesamteffekt, dass ein serialisierter Wert, Gruppen, erstellt wird, dessen Quelle die gewünschte Mitgliedschaft ist, und anschließend ein benutzerdefinierter Serializer verwendet wird, um die anzuzeigenden Bits herauszuholen.
BEARBEITEN: Wie von @bryanph kommentiert,
serializers.field
wurdeserializers.ReadOnlyField
in DRF 3.0 umbenannt, daher sollte dies lauten:für alle modernen Implementierungen
quelle
membership_set
ist der Standardname für Mitglied -> MitgliedschaftIch war mit diesem Problem konfrontiert und meine Lösung (unter Verwendung von DRF 3.6) bestand darin, SerializerMethodField für das Objekt zu verwenden und die Mitgliedschaftstabelle explizit wie folgt abzufragen:
Dies gibt eine Liste von Diktaten für den Gruppenschlüssel zurück, in dem jedes Diktat vom MembershipSerializer serialisiert wird. Um es beschreibbar zu machen, können Sie im MemberSerializer Ihre eigene Erstellungs- / Aktualisierungsmethode definieren, bei der Sie die Eingabedaten durchlaufen und explizit Mitgliedschaftsmodellinstanzen erstellen oder aktualisieren.
quelle
HINWEIS: Als Software-Ingenieur verwende ich gerne Architekturen und habe intensiv an einem mehrschichtigen Ansatz für die Entwicklung gearbeitet, daher werde ich ihn in Bezug auf Ebenen beantworten.
Wie ich das Problem verstanden habe, ist hier die Lösungsmodelle.py
serializers.py
CustomModels.py
BusinessLogic.py
Sie müssten die Anforderung technisch an DataAccessLayer übergeben, der die gefilterten Objekte aus der Datenzugriffsschicht zurückgibt, aber da ich die Frage schnell beantworten muss, habe ich den Code in der Geschäftslogikebene angepasst!
quelle