2016-11-21 2 views
1

Ich schreibe ein Stück Code, der POSTs von einem ColdFusion-System nehmen muss, die sehr unflexibel ist, wenn es um JSON geht, und ich habe nicht viel Kontrolle darüber sowieso. Ich habe ein Problem, bei dem manchmal ein auf ColdFusion laufendes automatisches System "leere" DecimalFields als "" sendet. Dies führt zu einem Fehler bei der Überprüfung in Django, weil DecimalFields kann nicht von einem leeren String umgewandelt werden: Django REST-Framework erhalten "bad" DecimalField, aber kein Fehler out

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

JSON

, dass es nicht ...

"TOTAL_DEFECTS":"", 

Das ist nur ein Null-Feld erzeugen sollte, sondern es Fehler aus, sagen, das ist nicht gültig. Technisch ist es nicht da, natürlich, können Sie dies in Python nicht tun können:

import decimal 
decimal.Decimal("") 

Um dies zu umgehen, habe ich in der Dispatch-Routine des Viewset gehackt. Ich habe mich gefragt, ob es einen besseren Weg gibt, dies zu tun. Hack-y-Code:

@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 

Das für diesen speziellen Fall funktioniert, aber ich denke, wahrscheinlich etwa so weit vom Ideal entfernt ist, wie ich bekommen kann. Gibt es eine django-ähnliche Möglichkeit, dies zu tun, anstatt dieses HttpRequest-Objekt neu zu schreiben, das nicht neu geschrieben werden soll?

Antwort

0

Ja, es gibt einen besseren Weg! Ihre Antwort ist customize the CharField options im Serializer. Ich würde additional arguments verwenden Sie den Code trocken zu halten, gehen Sie wie folgt:

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 

Natürlich würden Sie MyModel wechseln müssen, MyView und MySerializer mit Ihrem tatsächlichen Serializer und Aussicht.

Verwandte Themen