2016-09-25 1 views
2

Ich schreibe eine einfache Datenbank für die Wohnung, in der ich lebe, in der eine Liste von Personen, Einheiten, Einheitstyp (Heimat vs. Parkplatz) und Anteilinhaber (Join Tabelle für viele) zu viele Beziehungen zwischen einer Person und einer Einheit) - eine Person kann Eigentümer eines Einheitstyps "Haus" sein, während sie einen Parkplatz mietet.Django REST Framework Serializer Rückgabe von Objekt anstelle von Daten

Das ist mein Modell:

class Person(models.Model): 
    first_name = models.CharField(max_length=30, null=False) 
    last_name = models.CharField(max_length=30, null=False) 
    phone = models.CharField(max_length=20) 
    email = models.EmailField(max_length=20) 

class UnitType(models.Model): 
    description = models.CharField(max_length=30) 

class Unit(models.Model): 
    unit_number = models.IntegerField(null=False, unique=True) 
    unit_type = models.ForeignKey(UnitType, null=False) 
    unitholders = models.ManyToManyField(Person, through='UnitHolder') 

class UnitHolderType(models.Model): 
    description = models.CharField(max_length=30) 

class UnitHolder(models.Model): 
    person = models.ForeignKey(Person) 
    unit = models.ForeignKey(Unit) 
    unitholder_type = models.ForeignKey(UnitHolderType) 

Das ist meine Ansicht ist:

class UnitSerializer(serializers.ModelSerializer): 
    unit_type = serializers.SlugRelatedField(
     queryset=UnitType.objects.all(), slug_field='description' 
    ) 

    class Meta: 
     model = Unit 
     fields = ('unit_number', 'unit_type', 'unitholders') 

class UnitTypeSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = UnitType 

class PersonSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Person 

class UnitHolderSerializer(serializers.ModelSerializer): 
    person = serializers.PrimaryKeyRelatedField(many=False, read_only=True) 
    unit = serializers.PrimaryKeyRelatedField(many=False, read_only=True) 

    class Meta: 
     model = UnitHolder 
     fields = ('person', 'unit', 'unitholder_type') 

class UnitHolderTypeSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = UnitHolderType 

Das Problem:

Wenn ich Abfrage

class PersonViewSet(viewsets.ModelViewSet): 
    queryset = Person.objects.all() 
    serializer_class = PersonSerializer 

class UnitHolderTypeViewSet(viewsets.ModelViewSet): 
    queryset = UnitHolderType.objects.all() 
    serializer_class = UnitHolderTypeSerializer 

class UnitViewSet(viewsets.ModelViewSet): 
    queryset = Unit.objects.all() 
    serializer_class = UnitSerializer 

class UnitHolderViewSet(viewsets.ModelViewSet): 
    queryset = UnitHolder.objects.all() 
    serializer_class = UnitHolderSerializer 

class UnitTypeViewSet(viewsets.ModelViewSet): 
    queryset = UnitType.objects.all() 
    serializer_class = UnitTypeSerializer 

Das ist mein Serializer ist der/units Endpunkt l ike folgendes:

u = requests.get('http://localhost:8000/units').json() 

Meine Antwort wie folgt aussieht:

[{'unit_type': 'Home', 'unit_number': 614, 'unitholders': [1]}] 

Was ich zurück will, ist so etwas wie dieses:

[ 
    { 
     'unit_type': 'Home', 
     'unit_number': 614, 
     'unitholders': [ 
      { 
       'id: 1, 
       'first_name': 'myfirstname', 
       'last_name': 'mylastname', 
       'unitholder_type': 'renter' 
      } 
     ] 
    } 
] 

Ich bin ziemlich sicher, mein Problem ist in meinem UnitSerializer, aber ich bin brandneu zu DRF und lesen Sie die durch die Dokumentation, aber immer noch nicht scheinen, es herauszufinden.

Antwort

0

Vielleicht müssen Sie tun Somethings so:

class UnitHolderViewSet(viewsets.ModelViewSet): 
    queryset = UnitHolder.objects.all() 
    unitholders = UnitHolderSerializer(read_only=True, many=True) 

Django rest framework serializing many to many field

+0

hmm. Vielen Dank. Ich habe das nur meiner Meinung hinzugefügt, aber es hatte keine Wirkung. Abfragen dieses Endpunkts gibt immer noch zurück: [{'unit_type': 'Home', 'unit_number': 614, 'Anteilinhaber': [1]}] – Progger

3

Eine einfache Lösung wäre depth Option verwenden:

class UnitSerializer(serializers.ModelSerializer): 
    unit_type = serializers.SlugRelatedField(
     queryset=UnitType.objects.all(), slug_field='description' 
    ) 

    class Meta: 
     model = Unit 
     fields = ('unit_number', 'unit_type', 'unitholders') 
     depth = 1 

Dies wird alle geschachtelten Beziehungen 1 Ebene tief serialisiert. Wenn Sie feine Kontrolle darüber, wie jedes verschachtelte Feld wird serialisiert haben wollen, können Sie ihre Serializer explizit aufzulisten:

class UnitSerializer(serializers.ModelSerializer): 
    unit_type = serializers.SlugRelatedField(
     queryset=UnitType.objects.all(), slug_field='description' 
    ) 
    unitholders = UnitHolderSerializer(many=True) 

    class Meta: 
     model = Unit 
     fields = ('unit_number', 'unit_type', 'unitholders') 

Auch als eine Randnotiz, müssen Sie Ihre querysets Innenansichten zu prefetch related objects Blick in modifizieren, sonst Sie wird die App-Leistung sehr schnell zerstören (mit etwas wie django-debug-toolbar für die Überwachung generierter Abfragen ist sehr praktisch):

+0

danke! Das ist alles sehr hilfreich. depth = 1 hat bei mir funktioniert, aber den Serializer explizit durch Fehler aufgelistet. Ich werde versuchen, diese selbst auszuarbeiten :) – Progger

+0

Ich habe gerade festgestellt, dass "'anitholdertype': 'renter'" nicht zurückgegeben wird. Anteilinhaber-Typ wird in einer Join-Tabelle gehalten, die "Einheit" und "Person" assoziiert. Ich möchte nicht nur die Einheit zurückgeben, die mit der Person verknüpft ist, sondern auch den Zuordnungstyp, der in der Verknüpfung selbst enthalten ist. – Progger

Verwandte Themen