2017-08-24 2 views
0

J'ai une classe Object avec une méthode state qui prend un paramètre datetime dt. Comment puis-je passer le paramètre datetime de l'URL à Object.state()?Passer le paramètre au sérialiseur de structure Django REST à utiliser avec le modèle

Le modèle:

class Object(models.Model): 
    def state(self, dt=datetime.datetime.now()) -> dict: 
     ...stuff... 
     return {'dt': dt, 'other_stuff': stuff} 

La vue:

class ObjectDetail(generics.RetrieveAPIView): 
    queryset = models.Object.objects.all() 
    serializer_class = serializers.ObjectSerializer 

    def get_serializer_context(self): 
     return {'dt': self.request.query_params.get('dt', datetime.datetime.now())} 

    def get(self, request, *args, **kwargs): 
     return self.retrieve(request, *args, **kwargs) 

Et les classes sérialiseur:

class ObjectSerializer(serializers.HyperlinkedModelSerializer): 
    state = StateSerializer(read_only=True, context={'dt': self.context['dt']}) 

    class Meta: 
     model = models.Object 
     fields = ('state') 

class StateSerializer(serializers.Serializer): 
    dt = serializers.DateTimeField() 
    ... other stuff... 

Comme vous pouvez le voir, je suis en train de passer dt en tant que contexte supplémentaire dans la ligne state = StateSerializer(read_only=True, context={'dt': dt}) ayant défini le contexte plus tôt dans la vue. Le problème ici est que lorsque ObjectSerializer est initialisé dt n'est pas accessible via self.context['dt'] car self n'est pas défini.

+0

Quel est le but de 'state'? Devrait-il être mis à jour chaque fois que l'objet est sauvegardé ou qu'il a une autre idée? – wencakisa

+0

@wencakisa 'state' dépend de' dt' passé. Il est généré à partir de l'état de l'objet et d'autres choses et est un dict. Ce n'est pas accessible en écriture. – Tintin

Répondre

1

La solution est de faire state un serializers.SerializerMethodField() puis définir une méthode get_state. Le nouveau ObjectSeializer ressemble à ceci:

class ObjectSerializer(serializers.HyperlinkedModelSerializer): 
    state = serializers.SerializerMethodField() 

    class Meta: 
     model = models.Object 
     fields = ('state') 

    def get_state(self, obj): 
     state = obj.state(self.context['dt']) 
     state_serializer = StateSerializer(state) 
     return state_serializer.data