2012-11-20 15 views
5

Il mio modello è simile al seguente:Come estendere il modello a livello serializzatore con django-resto-quadro

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() 

Quello che mi piacerebbe fare è esporre un elenco dei componenti (non MenuItemComponents) in data MenuItem che includerebbe il campo isReplaceable. Finora ho:

#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 

che espone un elenco di MenuItemComponents e clienti forze per rendere più chiamate al fine di recuperare tutti i componenti. L'elenco dei componenti di Exposing con dati aggiuntivi dal campo isReplace potrebbe risolvere il problema.

EDIT
Alla fine mi piacerebbe avere una lista che elenca gli elementi componenti, ma gli elementi sono exteded con il campo da isReplaceable MenuItemComponent modello:

{ 
    "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

Potresti forse dare un esempio di come vorresti che fosse la rappresentazione finale? –

risposta

8

In primo luogo, creare una vista che sarà restituire le istanze MenuItemComponent che siete interessati.

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) 

Poi è necessario creare un serializzatore per darvi la rappresentazione che si desidera. Il vostro esempio è un po 'più interessante/coinvolti di quanto il caso tipico, in modo che sarebbe sembrare qualcosa di simile ...

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

I campi 'nome' e 'isReplaceable' può semplicemente utilizzare il valore predefinito di sola lettura Field classe.

Non c'è campo che soddisfi il vostro caso abbastanza 'url' qui, in modo creeremo un campo personalizzato per questo:

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) 

Penso che dovrebbe essere tutti circa la destra.

Questo è per una serializzazione di sola lettura: se si desidera una serializzazione scrivibile, è necessario esaminare il metodo restore_object sul serializzatore e utilizzare WritableField o qualcosa del genere.

+0

Ottimo, è stato il trucco. Grazie :). –

+0

Felice di sentirlo. –

Problemi correlati