2016-12-23 5 views
1

Ich frage mich, was der beste Weg, dies zu lösen, ich habe eine verschachtelte Serializer wie folgt aus:Django Übriges Framework Objekt request.data hinzufügen und dann Serializer is_valid() aufrufen

serializers.py:

class PaymentMethodSerializer(serializers.ModelSerializer): 

    data = serializers.JSONField() 
    payment_type = PaymentTypeSerializer(required=False) 

Dann sieht der Blick etwas wie folgt aus:

class PaymentMethodView(APIView): 
    def put(self, request, id): 

     try: 
      payment_method = PaymentMethod.objects.get(id=id) 
     except ObjectDoesNotExist: 
      return Response("No PaymentMethod with that id", status=status.HTTP_404_NOT_FOUND) 

     payment_method_serialized = PaymentMethodSerializer(instance=payment_method, data=request.data) 
     payment_type = request.data.get("payment_type", None) 

     if payment_type: 
      try: 
       payment_method_type = PaymentType.objects.get(id=payment_type) 
      except ObjectDoesNotExist: 
       payment_method_type = None 
     else: 
      payment_method_type = None 

    # Now, call is_valid() 
     if payment_method_serialized.is_valid(): 
      payment_method_serialized.save(payment_type=payment_method_type) 
      return Response(payment_method_serialized.data, status=status.HTTP_200_OK) 

is_valid() Falsch zurück und dieser Fehler:

{"payment_type":{"non_field_errors":["Invalid data. Expected a dictionary, but got int."]}} 

Ich verstehe es, ich gebe dem Serializer eine pk. Ich möchte jedoch keinen neuen Serializer mit einer PrimaryKeyRelatedField anstelle der geschachtelten Beziehung nur dafür erstellen. Wie kann ich die PaymentType, die dieser pk entspricht, und dann dieses Objekt dem request.data Wörterbuch hinzufügen, so dass is_valid nicht fehlschlägt? Ist das der beste Weg, dies zu lösen?

Antwort

1

Angenommen payment_type ist ForeignKey Feld in einem PaymentMethod Modell mit null=True aufgrund required=False.
Wenn Sie nur eine pk angeben, so dass Sie kein Serializer für dieses Feld benötigen, können Sie einfach wie in allen anderen Feldern fields schreiben.

class PaymentMethodSerializer(serializers.ModelSerializer): 

    data = serializers.JSONField() 

    class Meta: 
     model = PaymentMethod 
     fields = ('data', 'payment_type') 

Es wird pk oder None akzeptieren. Wenn Sie für Ihr Modell PaymentType eine spezielle Darstellung bereitstellen möchten, können Sie eine to_representation()-Methode überschreiben.

class PaymentMethodSerializer(serializers.ModelSerializer): 

    ... 
    def to_representation(self, instance): 
     representation = super(PaymentMethodSerializer, self).to_representation(instance) 
     representation['payment_type'] = PaymentTypeSerializer(instance.payment_type).data 
     return representation 

Jetzt wird es PaymentTypeSerializer zur Darstellung verwandten PaymentType Modell verwenden.
Sie können jedoch payment_type Validierung in einem serializer verschieben. Überschreiben Sie to_internal_value, überprüfen Sie PaymentType PK und werfen Sie eine Ausnahme, wenn es falsch ist und dann diese Ausnahme in einer Ansicht abfangen.

+0

Dank Ivan. Obwohl ich dieser Lösung nicht gefolgt bin. Ich fand den letzten Absatz sehr hilfreich: "Sie können die payment_type-Validierung jedoch in einen Serializer verschieben. Überschreiben Sie to_intern_value, prüfen Sie den bereitgestellten PaymentType pk und werfen Sie eine Ausnahme, wenn sie falsch ist, und fangen Sie dann diese Ausnahme in einer Ansicht ab." Deshalb habe ich diese Antwort akzeptiert. – alejoss

+0

@alejoss Ihr Willkommen –

Verwandte Themen