들어오는 Django 요청의 JSON 데이터는 어디에 있습니까?


168

Django / Python으로 들어오는 JSON / Ajax 요청을 처리하려고합니다.

request.is_ajax()True요청에,하지만 난 페이로드는 JSON 데이터를 함께 아무 생각이 없습니다.

request.POST.dir 포함 :

['__class__', '__cmp__', '__contains__', '__copy__', '__deepcopy__', '__delattr__',
 '__delitem__', '__dict__', '__doc__', '__eq__', '__ge__', '__getattribute__',
'__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__',
 '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__setitem__', '__str__', '__weakref__', '_assert_mutable', '_encoding', 
'_get_encoding', '_mutable', '_set_encoding', 'appendlist', 'clear', 'copy', 'encoding', 
'fromkeys', 'get', 'getlist', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 
'keys', 'lists', 'pop', 'popitem', 'setdefault', 'setlist', 'setlistdefault', 'update', 
'urlencode', 'values']

요청 게시 키에는 분명히 키가 없습니다.

Firebug 에서 POST를 보면 JSON 데이터가 요청에 전송됩니다.


실제로 무엇을 게시하고 있습니까? 자바 스크립트 호출을 보여주세요.
Daniel Roseman

그리고 len(request.POST)하고 request.POST.items()또한 도움이 될 것이다.
Vinay Sajip

답변:


236

Django에 JSON을 게시하는 경우 원한다고 생각합니다 request.body( request.raw_post_dataDjango <1.4). 그러면 게시물을 통해 전송 된 원시 JSON 데이터가 제공됩니다. 거기에서 추가로 처리 할 수 ​​있습니다.

다음은 JavaScript, jQuery , jquery-json 및 Django 를 사용한 예 입니다.

자바 스크립트 :

var myEvent = {id: calEvent.id, start: calEvent.start, end: calEvent.end,
               allDay: calEvent.allDay };
$.ajax({
    url: '/event/save-json/',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    data: $.toJSON(myEvent),
    dataType: 'text',
    success: function(result) {
        alert(result.Result);
    }
});

장고 :

def save_events_json(request):
    if request.is_ajax():
        if request.method == 'POST':
            print 'Raw Data: "%s"' % request.body   
    return HttpResponse("OK")

Django <1.4 :

  def save_events_json(request):
    if request.is_ajax():
        if request.method == 'POST':
            print 'Raw Data: "%s"' % request.raw_post_data
    return HttpResponse("OK")

'테스트 클라이언트'가 의미하는 바를 설명해주세요. 무엇을하려고합니까?
Jared Knipp 2011 년

무례하게 굴지 않으려 고합니다. "테스트 클라이언트"란 django "테스트 클라이언트"를 의미합니다. 테스트 클라이언트가 아닌 경우 뷰를 어떻게 테스트합니까?
jMyles 2011

4
주의 사항 : URL은 슬래시 (/) 문자로 끝나야합니다. @csrf_exempt와 또한 비활성화 CSRF
대니 헤레라

46
NB 1.4를 사용하는 경우 request.body라고합니다. raw_post_data는 ...되지 않습니다
prauchfuss

3
django unittest로 테스트하려면 그냥하세요self.client.post('/event/save-json/', json.dumps(python_dict), HTTP_X_REQUESTED_WITH='XMLHttpRequest', content_type="application/json")
Guillaume Vincent

73

나는 같은 문제가 있었다. 복잡한 JSON 응답을 게시했는데 request.POST 사전을 사용하여 데이터를 읽을 수 없었습니다.

내 JSON POST 데이터는 다음과 같습니다.

//JavaScript code:
//Requires json2.js and jQuery.
var response = {data:[{"a":1, "b":2},{"a":2, "b":2}]}
json_response = JSON.stringify(response); // proper serialization method, read 
                                          // http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
$.post('url',json_response);

이 경우 aurealus에서 제공하는 방법을 사용해야합니다. request.body를 읽고 json stdlib로 역 직렬화하십시오.

#Django code:
import json
def save_data(request):
  if request.method == 'POST':
    json_data = json.loads(request.body) # request.raw_post_data w/ Django < 1.4
    try:
      data = json_data['data']
    except KeyError:
      HttpResponseServerError("Malformed data!")
    HttpResponse("Got json data")

2
네 번째 줄에 문제 json_data = simplejson.loads(request.raw_post_data)가 있습니다. 정확히 말씀 하셨나요?
wfbarksdale 2011

이 예제를 테스트에서 사용한 것과 같이 request.raw_post_data가 올바른 형식이라고 확신합니다. @weezybizzle에 어떤 종류의 문제가 있습니까?
stricjux 2011

1
추가 텍스트로 들어오는 데이터도 파싱을 망쳐 놓았습니다. 그래서 100 % 저였습니다.
wfbarksdale 2011

4
django.utils.simplejson최근 버전에서 제거되었습니다. stdlib json라이브러리를 사용하십시오 .
Martijn Pieters

Django 1.4+의 경우 request.raw_post_data 대신 request.body를 사용하고 싶을 것입니다
mrooney

39

방법 1

클라이언트 : 다음으로 보내기 JSON

$.ajax({
    url: 'example.com/ajax/',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    processData: false,
    data: JSON.stringify({'name':'John', 'age': 42}),
    ...
});

//Sent as a JSON object {'name':'John', 'age': 42}

서버 :

data = json.loads(request.body) # {'name':'John', 'age': 42}

방법 2

클라이언트 : 다른 이름으로 보내기 x-www-form-urlencoded
(참고 : contentType& processData변경됨, JSON.stringify필요 없음)

$.ajax({
    url: 'example.com/ajax/',
    type: 'POST',    
    data: {'name':'John', 'age': 42},
    contentType: 'application/x-www-form-urlencoded; charset=utf-8',  //Default
    processData: true,       
});

//Sent as a query string name=John&age=42

서버 :

data = request.POST # will be <QueryDict: {u'name':u'John', u'age': 42}>

1.5 이상에서 변경 : https://docs.djangoproject.com/en/dev/releases/1.5/#non-form-data-in-http-requests

HTTP 요청의 비 양식 데이터 :
request.POST는 헤더에 비 양식 특정 콘텐츠 유형이있는 HTTP 요청을 통해 게시 된 데이터를 더 이상 포함하지 않습니다. 이전 버전에서 multipart / form-data 또는 application / x-www-form-urlencoded 이외의 콘텐츠 유형으로 게시 된 데이터는 여전히 request.POST 속성에 표시됩니다. 이러한 경우에 원시 POST 데이터에 액세스하려는 개발자는 대신 request.body 속성을 사용해야합니다.

아마도 관련이 있음


3
1 재 -django.http.request.RawPostDataException: You cannot access body after reading from request's data stream
AlxVallejo

25

기억하는 것이 중요합니다. Python 3에는 문자열을 나타내는 다른 방법이 있습니다. 즉, 바이트 배열입니다.

Django 1.9 및 Python 2.7을 사용하고 헤더가 아닌 본문에 JSON 데이터를 전송하면 다음과 같이 사용할 수 있습니다.

mydata = json.loads(request.body)

그러나 Django 1.9 및 Python 3.4의 경우 다음을 사용합니다.

mydata = json.loads(request.body.decode("utf-8"))

이 학습 곡선을 통해 첫 번째 Py3 Django 앱을 만들었습니다!


3
설명해 주셔서 감사합니다! Django 1.10과 Python 3.5를 사용하고 있습니다. mydata = json.loads (request.body.decode ( "utf-8")) 작동합니다!
Julia Zhao

23

request.raw_response이제 더 이상 사용되지 않습니다. request.body대신 XML 페이로드, 이진 이미지 등과 같은 비 전통적인 양식 데이터를 처리하는 데 사용 합니다.

문제에 대한 장고 문서 .


9

장고 1.6 파이썬 3.3에서

고객

$.ajax({
    url: '/urll/',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    data: JSON.stringify(json_object),
    dataType: 'json',
    success: function(result) {
        alert(result.Result);
    }
});

섬기는 사람

def urll(request):

if request.is_ajax():
    if request.method == 'POST':
        print ('Raw Data:', request.body) 

        print ('type(request.body):', type(request.body)) # this type is bytes

        print(json.loads(request.body.decode("utf-8")))

5

HTTP POST 페이로드는 단순한 바이트입니다. Django (대부분의 프레임 워크와 마찬가지로)는 URL 인코딩 매개 변수 또는 MIME 멀티 파트 인코딩에서 사전으로 디코딩합니다. POST 콘텐츠에 JSON 데이터 만 덤프하면 Django는 디코딩하지 않습니다. 사전이 아닌 전체 POST 콘텐츠에서 JSON 디코딩을 수행합니다. 또는 JSON 데이터를 MIME 멀티 파트 래퍼에 넣습니다.

간단히 말해서 JavaScript 코드를 보여줍니다. 문제가있는 것 같습니다.


나는 지금 문제를 본다! jquery의 type = 'json'매개 변수는 전송되는 것이 아니라 예상되는 유형을 참조합니다. 일반 형식 포스트 인코딩 데이터를 보내고 있으므로 "json"을 보내려면 어떻게 든 문자열로 변환하고 "json = {foo : bar,}"등을 전달해야합니다. 그러나 믿을 수는 없습니다. 대부분의 사람들이 어떻게하는지. 여기 뭔가 빠졌 나봐요.

실제로 .serialize () 함수를 사용하여 jQuery에서 양식을 JSON 문자열로 변환 할 수 있습니다. 하지만 왜 특히 json을 보내야합니까? 양식 데이터를 보내는 데 문제가 있습니까?
Daniel Roseman

4
원시 양식 데이터가 충분하지 않은 경우가 많이 있습니다. JSON을 사용하면 키 : 값 쌍뿐만 아니라 계층 적 객체를 보낼 수 있습니다. 중첩 된 집합, 배열 등을 보낼 수 있습니다. 포스트 데이터로 모든 작업을 수행 할 수 있지만 그렇게 편리하지는 않습니다. 항상 JSON을 처리하는 것이 좋습니다
Taxilian

5

request.raw_post_data더 이상 사용되지 않습니다. 사용 request.body하는 대신


감사합니다! 완벽하게 작동했습니다.
Prometheus

4

이 같은. 작동했습니다 : 클라이언트에서 데이터 요청

registerData = {
{% for field in userFields%}
  {{ field.name }}: {{ field.name }},
{% endfor %}
}


var request = $.ajax({
   url: "{% url 'MainApp:rq-create-account-json' %}",
   method: "POST",
   async: false,
   contentType: "application/json; charset=utf-8",
   data: JSON.stringify(registerData),
   dataType: "json"
});

request.done(function (msg) {
   [alert(msg);]
   alert(msg.name);
});

request.fail(function (jqXHR, status) {
  alert(status);
});

서버에서 요청 처리

@csrf_exempt
def rq_create_account_json(request):
   if request.is_ajax():
       if request.method == 'POST':
           json_data = json.loads(request.body)
           print(json_data)
           return JsonResponse(json_data)
   return HttpResponse("Error")

2
html code 

file name  : view.html


    <!DOCTYPE html>
    <html>
    <head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script>
    $(document).ready(function(){
        $("#mySelect").change(function(){
            selected = $("#mySelect option:selected").text()
            $.ajax({
                type: 'POST',
                dataType: 'json',
                contentType: 'application/json; charset=utf-8',
                url: '/view/',
                data: {
                       'fruit': selected
                      },
                success: function(result) {
                        document.write(result)
                        }
        });
      });
    });
    </script>
    </head>
    <body>

    <form>
        <br>
    Select your favorite fruit:
    <select id="mySelect">
      <option value="apple" selected >Select fruit</option>
      <option value="apple">Apple</option>
      <option value="orange">Orange</option>
      <option value="pineapple">Pineapple</option>
      <option value="banana">Banana</option>
    </select>
    </form>
    </body>
    </html>

Django code:


Inside views.py


def view(request):

    if request.method == 'POST':
        print request.body
        data = request.body
        return HttpResponse(json.dumps(data))

-2

Angular를 사용하여 요청에 헤더를 추가하거나 모듈 구성 헤더에 추가해야합니다. {'Content-Type': 'application/x-www-form-urlencoded'}

$http({
    url: url,
    method: method,
    timeout: timeout,
    data: data,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})

-4

request.POST는 딕셔너리와 유사한 객체이므로 dict 구문을 사용하여 색인화하면됩니다.

양식 필드가 fred라고 가정하면 다음과 같이 할 수 있습니다.

if 'fred' in request.POST:
    mydata = request.POST['fred']

또는 양식 객체를 사용하여 POST 데이터를 처리합니다.


아무것도 포함하지 않은 request.POST [ 'json']을 찾고있었습니다. len은 0

그러면 Daniel이 제안한대로 JavaScript 호출을 보는 것이 확실히 도움이 될 것입니다.
Vinay Sajip

13
request.POST는 POST 요청의 본문이 Form 인코딩 된 경우에만 채워지며, 그렇지 않으면 비어 있습니다.
slacy apr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.