2012-11-20 9 views
5

Mein Modell erweitern sieht wie folgt aus:Wie Modell auf Serializer Ebene mit django-Rest-Rahmen

class MenuItem(models.Model): 
    name = models.CharField(max_length=500) 
    components = models.ManyToManyField(Component, through=MenuItemComponent) 

class Component(models.Model): 
    name = models.CharField(max_length=500) 

class MenuItemComponent(models.Model): 
    menuItem = models.ForeignKey('MenuItem') 
    component = models.ForeignKey(Component) 
    isReplaceable = models.BooleanField() 

Was ich zu tun ist, möchte eine Liste von Komponenten (nicht MenuItemComponents) in bestimmten MenuItem, dass er würde das isReplaceable-Feld enthalten. Bisher habe ich:

#views.py 

class MenuItemComponentList(generics.ListAPIView): 
    """ 
    Displays components for given MenuItem 
    """ 
    model = MenuItemComponent 
    serializer_class = MenuItemComponentSerializer 

    def get_queryset(self): 
     itemId = self.kwargs['itemId'] 
     return MenuItemComponent.objects.filter(menuItem__pk=itemId) 



#serializers.py 

class MenuItemComponentSerializer(serializers.HyperlinkedModelSerializer): 
    class Meta: 
     model = MenuItemComponent 

, die eine Liste von MenuItemComponents und zwingt Clients zur Verfügung stellt, um mehrere Anrufe zu machen, um alle Komponenten abzurufen. Wenn Sie die Komponentenliste mit zusätzlichen Daten aus dem Feld isReplaceable öffnen, wird das Problem gelöst.

EDIT
Am Ende wird Ich möchte eine Liste erhalten, die Komponentenelemente, sondern die Elemente listet exteded mit isReplaceable Feld von MenuItemComponent Modell:

{ 
    "count": 2, 
     "next": null, 
     "previous": null, 
     "results": [ 
     { 
      "url": "http://localhost:8000/api/component/1/", 
      "name": "component 1", 
      "isReplaceable": true 
     }, 
     { 
      "url": "http://localhost:8000/api/component/2/", 
      "name": "component 2", 
      "isReplaceable": false 
     } 
    ] 
} 
+0

Können Sie vielleicht ein Beispiel geben, wie die endgültige Darstellung aussehen soll? –

Antwort

8

Zuerst eine Ansicht erstellen, wird geben die MenuItemComponent Instanzen, die Sie interessieren.

class ListComponents(generics.ListAPIView): 
    serializer_class = MenuItemComponentSerializer 

    def get_queryset(self): 
     """ 
     Override .get_queryset() to filter the items returned by the list. 
     """ 
     menuitem = self.kwargs['menuitem'] 
     return MenuItemComponent.objects.filter(menuItem=menuitem) 

Dann müssen Sie einen Serializer erstellen Sie die Darstellung, die Sie wollen, zu geben. Ihr Beispiel ist ein wenig interessanter/Beteiligten als der typische Fall, so ist es in etwa so aussehen würde ...

class MenuItemComponentSerializer(serializers.Serializer): 
    url = ComponentURLField(source='component') 
    name = Field(source='component.name') 
    isReplaceable = Field() 

‚Name‘ Felder und ‚isReplaceable‘ kann einfach verwenden, um die Standard-Nur-Lese-Field Klasse.

Es gibt kein Feld, das ganz hier Ihren ‚url‘ Fall erfüllt, so dass wir ein benutzerdefiniertes Feld für die erstellen:

class ComponentURLField(serializers.Field): 
    def to_native(self, obj): 
     """ 
     Return a URL, given a component instance, 'obj'. 
     """ 

     # Something like this... 
     request = self.context['request'] 
     return reverse('component-detail', kwargs=kwargs, request=request) 

Ich denke, dass alles über Recht sein sollte.

Das ist für eine schreibgeschützte Serialisierung - wenn Sie eine beschreibbare Serialisierung wollten, müssen Sie die restore_object Methode auf dem Serializer überschreiben und WritableField oder etwas in dieser Richtung verwenden.

+0

Großartig, das hat den Trick gemacht. Vielen Dank :). –

+0

Freut mich zu hören. –

Verwandte Themen