Django REST框架接收“坏”DecimalField但不会出错

时间:2016-11-21 18:01:22

标签: python django

我正在编写一段需要从ColdFusion系统中获取POST的代码,这在JSON方面非常不灵活,而且我无论如何都无法控制它。我有一个问题,有时在ColdFusion上运行的自动系统会将“空”DecimalFields发送为“”。这会导致Django中的验证错误,因为无法从空字符串转换DecimalField:

TOTAL_DEFECTS = models.DecimalField(max_digits=10, decimal_places=2, null = True)

失败的JSON ......

"TOTAL_DEFECTS":"",

那应该只产生一个空字段,但是它会出错,说这是无效的。从技术上讲,当然不是因为你不能用Python做到这一点:

import decimal
decimal.Decimal("")

为了处理这个问题,我已经入侵了viewset的调度例程。我想知道是否有更好的方法来做到这一点。 Hack-y代码:

@csrf_exempt # Because ColdFusion can't handle CSRF headers
def dispatch(self, request, *args, **kwargs):
    repregex = re.compile(r'"",') # This is actually done elsewhere in the real code
    nbody = repregex.sub('null,', request.body)
    request._body = nbody
    request._stream = BytesIO(nbody)
    a = super(XViewSet, self).dispatch(request, *args, **kwargs)
    if a.status_code != 201:
        #log errors here
        pass
    return a

这适用于这个特定情况,但我认为可能与我能得到的理想情况相差甚远。除了重写这个不打算重写的HttpRequest对象之外,还有更多的Django-ish方法吗?

1 个答案:

答案 0 :(得分:0)

是的,还有更好的方法!您的答案是序列化程序中的customize the CharField options。我会使用additional arguments来保存代码DRY,这里是如何:

from rest_framework import serializers
from rest_framework.generics import ListCreateAPIView


class MySerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel
        fields = '__all__'
        extra_kwargs = {'TOTAL_DEFECTS': {'allow_blank': True}}


class MyView(ListCreateAPIView):
    serializer_class = MySerializer

当然,您必须使用实际的序列化程序和视图切换MyModelMyViewMySerializer