2016-06-29 3 views
2

Angenommen, ich habe diese Modelle:Optional retrieve verwandte Elemente in Django REST Rahmen

class House(models.Model): 
    name = models.CharField(max_length=50) 
    # Other attributes 

class Booking(models.Model): 
    house = models.ForeignKey(House, on_delete=models.CASCADE) 
    arrival_date = models.DateField() 
    departure_date = models.DateField() 

Serializer:

class HouseSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = House 
     fields = ('id','name') 

class BookingSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Booking 
     fields = ('id', 
        'arrival_date', 
        'departure_date', 
        'house') 

Wie Sie sehen können, Buchungen zu den Häusern verbunden sind.

Benutzer können Informationen über ein Haus über "/ house /: houseId" und Buchungen über "/ booking /: bookingId" anfordern.

Ich möchte alle Buchungen im Zusammenhang mit einem Haus zurückgeben, wenn ein Benutzer "/ Haus/Buchungen" anfordert, aber diese sollten nicht zurückgegeben werden, wenn einfach "/ Haus/Buchungen" anfordern, da dies eine relativ teure Operation ist wird normalerweise nicht benötigt.

Ich weiß, wie man sie mit dem Haus zurückgibt, aber wie man dies optional macht. Wie mache ich das?

+1

Was ist der Unterschied zwischen den beiden Uris? –

Antwort

2

Erstens ist es (zumindest für mich) sinnvoller, Ihren Endpunkt für Buchungen für ein bestimmtes Haus unter /house/:houseId/bookings/ zu haben, da der Namensraum unter bereits nach einer ID sucht.

Sie können die Beziehung zwischen einem Haus und der Buchung auch serialisieren, um die Buchungen für ein Haus am Hausdetailendpunkt anzuzeigen. Etwas wie:

class HouseSerializer(serializers.ModelSerializer): 
    bookings = BookingSerializer(many=True) 

    class Meta: 
     model = House 
     fields = ('id','name', 'bookings',) 

Aber wenn Sie einen anderen Endpunkt möchten, erstellen Sie einfach eine Ansicht, die die BookingSerializer und filtert das queryset durch das Haus ID in den kwargs nimmt:

(Wieder unter der Annahme Ihr Endpunkt ist /house/<house_id>/bookings/)

class BookingsForHouseListView(ListAPIView): 
    serializer_class = BookingSerializer 

    def get_queryset(self): 
     return Bookings.objects.filter(house__id=self.kwargs['house_id']) 
+0

Danke, ich war mir der ListAPIView nicht bewusst, immer noch ein bisschen Anfänger mit Django. – user1582024

+0

Ist es auch möglich, den von Ihnen vorgeschlagenen HouseSerializer zu verwenden, die Buchungen jedoch nicht standardmäßig einzuschließen? (Wie ein Parameter, include_bookings = true) – user1582024

+0

Ich würde einen anderen Serializer erstellen (möglicherweise ein Kind von 'HouseSerializer') und überschreiben' get_serializer_class' in der Ansicht. Überprüfen Sie diese Website außerdem, um zu entscheiden, welche Methoden und Attribute Ihnen zur Verfügung stehen: http://www.cdrf.co/ –

0

Vielleicht können Sie zwei Serialisierer tun, einen auf der Liste der Häuser, ohne die Bücher zu zeigen, und einen anderen für das einzelne Haus, die Bücher zeigend.

In den Ansichten definieren Sie den Listen-Serializer für die Liste uri und den einzelnen Serializer für die einzelnen uri.

0

es stellt sich heraus, war ich mit zu hohen Ebene Teilen der API versucht, das mich mehr eingeschränkt, als sie mir halfen, brauchte ich manuell einige Dinge zu tun.

Diese Antwort https://stackoverflow.com/a/17763864/1582024 zeigt, wie eine Ressourcenhierarchie implementiert wird.

Verwandte Themen