我正在编写一段需要从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方法吗?
答案 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
当然,您必须使用实际的序列化程序和视图切换MyModel
,MyView
和MySerializer
。