为什么 Django 没有检测到我在 javascript fetch POST 请求中发送的数据?

Dav*_*ver 1 javascript python django fetch

我正在使用 fetch api 发布数据。在正文中,我发送了employee_id,但我收到来自 Django 的 MulitDictKey 错误,表示未收到它(以及其他数据)。为什么不发送?我缺少什么吗?

\n\n

在我的 html 文件中(在 script 标签中):

\n\n
const graduateEmployee = row => {\n        const token = row.querySelector(\'INPUT\').value\n        fetch(\'/questions/ajax/update_employee\', {\n                method: \'POST\',\n                headers: {\n                  "X-CSRFToken": token,\n                  "Accept": "application/json",\n                  \'Content-Type\': \'application/json\'\n                },\n                body:JSON.stringify({\n                    employee_id: row.id,\n                    column: \'mentor_status\',\n                    new_value: false\n                })\n            }).then((res) => res.json())\n            .then((response) =>  console.log(\'Success:\', JSON.stringify(response)))\n            .catch((err)=>console.log(\'Error:\', err))\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

在我的views.py中:

\n\n
def update_employee(request):\n    employee_id= int(request.POST["employee_id"])\n    column = request.POST["column"]\n    new_value = request.POST["new_value"]\n    employee = Employee.objects.get(employee_id = employee_id)\n    employee[column] = new_value\n    employee.save()\n    return HttpResponse(f\'{column} column for employee with id{employee_id} set to {new_value}\')\n
Run Code Online (Sandbox Code Playgroud)\n\n

错误页面:

\n\n
MultiValueDictKeyError at /questions/ajax/update_employee\n\'employee_id\'\nRequest Method: GET\nRequest URL:    http://127.0.0.1:8001/questions/ajax/update_employee\nDjango Version: 2.2.2\nException Type: MultiValueDictKeyError\nException Value:    \n\'employee_id\'\nException Location: C:\\Users\\dklaver\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages\\django\\utils\\datastructures.py in __getitem__, line 80\nPython Executable:  C:\\Users\\dklaver\\AppData\\Local\\Programs\\Python\\Python37-32\\python.exe\nPython Version: 3.7.1\nPython Path:    \n[\'C:\\\\Users\\\\dklaver\\\\mentor-program\\\\mentor\',\n \'C:\\\\Users\\\\dklaver\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37-32\\\\python37.zip\',\n \'C:\\\\Users\\\\dklaver\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37-32\\\\DLLs\',\n \'C:\\\\Users\\\\dklaver\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37-32\\\\lib\',\n \'C:\\\\Users\\\\dklaver\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37-32\',\n \'C:\\\\Users\\\\dklaver\\\\AppData\\\\Roaming\\\\Python\\\\Python37\\\\site-packages\',\n \'C:\\\\Users\\\\dklaver\\\\AppData\\\\Local\\\\Programs\\\\Python\\\\Python37-32\\\\lib\\\\site-packages\',\n \'C:\\\\Users\\\\dklaver\\\\mentor-program\\\\mentor\\\\helpers\',\n \'C:\\\\Users\\\\dklaver\\\\mentor-program\\\\mentor\\\\cron\']\nServer time:    Fri, 5 Jul 2019 17:42:18 +0000\nTraceback Switch to copy-and-paste view\nC:\\Users\\dklaver\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages\\django\\utils\\datastructures.py in __getitem__\n            list_ = super().__getitem__(key) \xe2\x80\xa6\n\xe2\x96\xb6 Local vars\nDuring handling of the above exception (\'employee_id\'), another exception occurred:\nC:\\Users\\dklaver\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages\\django\\core\\handlers\\exception.py in inner\n            response = get_response(request) \xe2\x80\xa6\n\xe2\x96\xb6 Local vars\nC:\\Users\\dklaver\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages\\django\\core\\handlers\\base.py in _get_response\n                response = self.process_exception_by_middleware(e, request) \xe2\x80\xa6\n\xe2\x96\xb6 Local vars\nC:\\Users\\dklaver\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages\\django\\core\\handlers\\base.py in _get_response\n                response = wrapped_callback(request, *callback_args, **callback_kwargs) \xe2\x80\xa6\n\xe2\x96\xb6 Local vars\nC:\\Users\\dklaver\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages\\django\\contrib\\auth\\decorators.py in _wrapped_view\n                return view_func(request, *args, **kwargs) \xe2\x80\xa6\n\xe2\x96\xb6 Local vars\nC:\\Users\\dklaver\\mentor-program\\mentor\\questions\\views.py in update_employee\n    employee_id= int(request.POST["employee_id"]) \xe2\x80\xa6\n\xe2\x96\xb6 Local vars\nC:\\Users\\dklaver\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages\\django\\utils\\datastructures.py in __getitem__\n            raise MultiValueDictKeyError(key) \xe2\x80\xa6\n\xe2\x96\xb6 Local vars\nRequest information\nGET\nNo GET data\n\nPOST\nNo POST data\n\nFILES\nNo FILES data\n
Run Code Online (Sandbox Code Playgroud)\n

Bob*_*ite 5

#Remember to put 'X-Requested-With':'XMLHttpRequest' to headers
const data = JSON.stringify({
    'hello':'world',
})

fetch('{% url "/questions/ajax/update_employee" %}', {
        method:'POST',
        headers:{
            'Content-Type':'application/json', 
            'X-CSRFToken':'{{csrf_token}}',
            'X-Requested-With':'XMLHttpRequest'
        },
        body:data,
        mode:'cors',
        cache:'default',
        credentials:'include'      
    }).then((response)=>{
        console.log('well');        
    })


def apiValues(self, request):
    data = json.loads(request.body)
    print(data.hello)
    return JsonResponse({'ok':True}, status=200)

#Result will be 'World'
Run Code Online (Sandbox Code Playgroud)

如果你想使用request.POST,那么你将需要发送一个formData而不是一个json。

如何使用 mozilla 的 FormData

var formData = new FormData();

formData.append("username", "Groucho");
formData.append("csrfmiddlewaretoken", "{{ csrf_token }");

fetch('{% url "/questions/ajax/update_employee" %}', {
        method:'post',
        body:formData ,
        mode:'cors',
        cache:'default',
        credentials:'include',            
    }).then((response)=>{
   console.log('well')
})
Run Code Online (Sandbox Code Playgroud)