2012-11-20 4 views
5

Mon modèle ressemble à ceci:Comment étendre le modèle au niveau sérialiseur avec django-repos-cadre

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

Ce que je voudrais faire est d'exposer une liste de composants (non MenuItemComponents) dans ligneMenu étant donné que inclurait le champ isReplaceable. Jusqu'à présent, j'ai:

#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 

qui expose une liste des clients et MenuItemComponents des forces pour faire plusieurs appels afin de récupérer tous les composants. L'exposition de la liste des composants avec des données supplémentaires provenant du champ isReplaceable résoudrait le problème.

EDIT
En fin de compte, je voudrais obtenir une liste qui répertorie les éléments constitutifs mais les éléments sont exteded avec le champ isReplaceable du modèle MenuItemComponent:

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

Pourriez-vous donner un exemple de ce à quoi vous voulez que la représentation finale ressemble? –

Répondre

8

D'abord, créer une vue qui va renvoyer les instances MenuItemComponent que vous intéressent.

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) 

Ensuite, vous devez créer un sérialiseur pour vous donner la représentation que vous voulez. Votre exemple est un peu plus intéressant/impliqué que dans le cas typique, il avait l'air quelque chose comme ça ...

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

Les nom de «champs et « isReplaceable » peut simplement utiliser la valeur par défaut en lecture seule Field classe.

Il n'y a pas tout à fait le terrain qui répond à votre cas « url » ici, donc nous allons créer un champ personnalisé pour que:

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) 

Je pense que tout devrait être à peu près juste. C'est pour une sérialisation en lecture seule - si vous vouliez une sérialisation inscriptible, vous devriez chercher à surcharger la méthode restore_object sur le sérialiseur, et en utilisant WritableField, ou quelque chose du genre.

+0

Super, ça a fait l'affaire. Je vous remercie :). –

+0

Content de l'entendre. –

Questions connexes