Django Rest Framework,将对象添加到request.data中,然后调用serializer is_valid() [英] Django Rest Framework, add object to request.data and then call serializer is_valid()

查看:1723
本文介绍了Django Rest Framework,将对象添加到request.data中,然后调用serializer is_valid()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



serializers.py:

  class PaymentMethodSerializer(serializers.ModelSerializer):

data = serializers.JSONField()
payment_type = PaymentTypeSerializer(required = F $)

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

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

try:
payment_method = PaymentMethod.objects.get(id = id)
除了ObjectDoesNotExist:
返回响应(No PaymentMethod with the 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)

如果payment_type:
try:
payment_met hod_type = PaymentType.objects.get(id = payment_type)
除了ObjectDoesNotExist:
payment_method_type =无
其他:
payment_method_type =无

#现在,调用is_valid()
如果payment_method_serialized.is_valid():
payment_method_serialized.save(payment_type = payment_method_type)
返回响应(payment_method_serialized.data,status = status.HTTP_200_OK)

is_valid()返回False,此错误:

  {payment_type:{non_field_errors:[无效的数据。预期一个字典,但有int。]}} 

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

解决方案

假设 payment_type ForeignKey field在 PaymentMethod 模型中, null = True 因为 required = False

如果你只提供一个 pk ,所以你不需要这个字段串行器,你可以写入字段,像所有其他字段。

  class PaymentMethodSerializer(serializers.ModelSerializer):

data = serializers.JSONField()

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

它将接受 pk 。如果要为您的 PaymentType 模型提供特殊表示,您可以覆盖 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

现在,它将使用PaymentTypeSerializer表示相关的 PaymentType 模型。 >
您可以在序列化程序中移动 payment_type 验证。覆盖 to_internal_value ,检查提供的 PaymentType pk,如果错误则抛出异常,然后在视图中捕获该异常。 / p>

I'm wondering which is the best way to solve this, I have a nested serializer like this:

serializers.py:

class PaymentMethodSerializer(serializers.ModelSerializer):

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

Then, the view looks something like this:

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() returns False and this error:

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

I understand it, I'm giving the serializer a pk. However I don't want to create a new serializer with a PrimaryKeyRelatedField instead of the nested relationship just for this. How can I get the PaymentType that corresponds to that pk and then add that object to the request.data dictionary so that is_valid doesn't fail? is it the best way to solve this?

解决方案

Suppose payment_type is ForeignKey field in a PaymentMethod model, with null=True because of required=False.
If you provide only a pk so you don't need serializer for it field, you can just write in fields, like all other fields.

class PaymentMethodSerializer(serializers.ModelSerializer):

    data = serializers.JSONField()

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

It will accept pk or None. If you want to provide special representation for your PaymentType model, you can override a to_representation() method.

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

Now it will use PaymentTypeSerializer for representation of related PaymentType model.
You can move you payment_type validation in a serializer though. Override to_internal_value, check provided PaymentType pk and throw an exception if it wrong and then catch that exception in a view.

这篇关于Django Rest Framework,将对象添加到request.data中,然后调用serializer is_valid()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆