2015-04-08 14 views
13

Wysyłam żądanie POST z ciałem JSON do serwera Django (dość standardowe). Na serwerze muszę to zdekodować, używając json.loads().Uzyskaj treść żądania jako ciąg znaków w Django

Problem polega na tym, w jaki sposób uzyskać treść żądania w formacie ciągu?

Mam następujący kod obecnie:

body_data = {} 
if request.META.get('CONTENT_TYPE', '').lower() == 'application/json' and len(request.body) > 0: 
    try: 
     body_data = json.loads(request.body) 
    except Exception as e: 
     return HttpResponseBadRequest(json.dumps({'error': 'Invalid request: {0}'.format(str(e))}), content_type="application/json") 

to jednak daje błąd the JSON object must be str, not 'bytes'.

Jak pobrać treść żądania w postaci ciągu znaków z poprawnym kodowaniem?

+0

Czy 'request.read()' wykonuje zadanie? – dhke

+0

@dhke, nie, daje to samo, co mnie naprawdę zaskoczyło. 'request.body.decode ('utf-8')' wydaje się działać, ale nie jestem pewien, czy jest to najlepszy sposób na zrobienie tego? – zelanix

Odpowiedz

26

Treść żądania, request.body, jest ciągiem bajtów. W języku Python 3, json.loads() będzie akceptował tylko ciąg znaków Unicode, dlatego musisz go zdekodować request.body przed przekazaniem go do json.loads().

body_unicode = request.body.decode('utf-8') 
body_data = json.loads(body_unicode) 

W Pythonie 2, json.loads akceptuje ciąg Unicode lub żądło bajtów, więc etap dekodowania nie jest konieczne.

Podczas dekodowania ciąg, myślę, że jesteś bezpieczny zakładać „utf-8” - nie mogę znaleźć ostateczne źródło w tym, ale patrz poniższy cytat z jQuery docs:

nocie : Specyfikacja W3C XMLHttpRequest określa, że ​​zestaw znaków zawsze ma UTF-8; określenie innego zestawu znaków nie zmusi przeglądarki do zmiany kodowania.

W języku Python 3.6, json.loads() accepts bytes or bytearrays. Dlatego nie trzeba dekodować request.body (zakładając, że jest zakodowany w UTF-8).

+0

Doskonale, dziękuję za wyjaśnienie tego :) – zelanix

+2

'utf-8' jest także domyślną wartością pierwszego argumentu metody' decode() '(sprawdź' help (bytes.decode) ') – rednaw

+2

W Pythonie> = 3.6, 'json.loads' może również zaakceptować argument' bytes' i zakłada, że ​​jest zakodowany w UTF-8, UTF-16 lub UTF-32. https://docs.python.org/3/library/json.html#json.loads – Flimm

0

Uważam, że drugi koniec, od którego otrzymujesz to żądanie, nie konwertuje danych do JSON przed wysłaniem żądania. Musisz przekonwertować dane do JSON przed wysłaniem lub po prostu spróbuj uzyskać dostęp do request.body w swoim widoku.

+1

Dzięki za odpowiedź. Myślę, że jest to poprawne json - jeśli użyję 'request.body.decode ('utf-8')' to działa. Czy jest jakiś powód, żeby tego nie robić? – zelanix

Powiązane problemy