Django Rest Framework,将对象添加到request.data然后调用序列化器is_valid()

时间:2016-12-23 22:16:55

标签: django django-rest-framework

我想知道哪种解决方法最好,我有一个这样的嵌套序列化器:

serializers.py:

class PaymentMethodSerializer(serializers.ModelSerializer):

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

然后,视图看起来像这样:

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()返回False并出现此错误:

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

我理解,我给序列化器pk。但是,我不想为此创建一个带有PrimaryKeyRelatedField而不是嵌套关系的新序列化程序。如何获取与PaymentType对应的pk,然后将该对象添加到request.data字典,以便is_valid不会失败?这是解决这个问题的最佳方法吗?

1 个答案:

答案 0 :(得分:1)

假设payment_type模型中的ForeignKeyPaymentMethod字段,null=Truerequired=False而为pk。 如果您只提供fields,那么您不需要为其显示序列化程序,您可以像所有其他字段一样写入class PaymentMethodSerializer(serializers.ModelSerializer): data = serializers.JSONField() class Meta: model = PaymentMethod fields = ('data', 'payment_type')

pk

它将接受NonePaymentType。如果您想为to_representation()模型提供特殊表示,则可以覆盖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 方法。

PaymentType

现在它将使用PaymentTypeSerializer来表示相关的payment_type模型 您可以在serializer中移动to_internal_value验证。覆盖PaymentType,检查提供的$command = 'ping -c 3 stackoverflow.com'; //shell_exec() shell_exec($command); //system() system($command); //`` `$command`; //exec() exec($command); //proc_open() $descriptorspec = array( 0 => array("pipe", "r"), // stdin is a pipe that the child will read from 1 => array("pipe", "w"), // stdout is a pipe that the child will write to 2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to ); $process = proc_open($command, $descriptorspec, $pipes); //passthru() passthru($command); pk,如果错误则抛出异常,然后在视图中捕获该异常。

相关问题