JSONDecodeError при попытке сделать счетчик запросов с помощью Django
Итак, я хотел сделать "reqcount" в моем проекте django, используя JSON файл, но когда я запускаю его, я получаю эту ошибку:
Environment:
Request Method: GET
Request URL: http://localhost:8000/testing/reqcount/
Django Version: 3.2.6
Python Version: 3.8.6
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.messages',
'django.contrib.staticfiles',
'testing']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback (most recent call last):
File "C:\Users\chris\.virtualenvs\WEBSITE-PTmWcCQQ\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\chris\.virtualenvs\WEBSITE-PTmWcCQQ\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\chris\Desktop\WEBSITE\testing\views.py", line 17, in req_count
return HttpResponse(json.load(f))
File "c:\users\chris\appdata\local\programs\python\python38\lib\json\__init__.py", line 293, in load
return loads(fp.read(),
File "c:\users\chris\appdata\local\programs\python\python38\lib\json\__init__.py", line 357, in loads
return _default_decoder.decode(s)
File "c:\users\chris\appdata\local\programs\python\python38\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "c:\users\chris\appdata\local\programs\python\python38\lib\json\decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
Exception Type: JSONDecodeError at /testing/reqcount/
Exception Value: Expecting value: line 1 column 1 (char 0)
Вот мой код views.py (игнорируйте функцию "hello"):
from django.shortcuts import render
from django.http import HttpResponse
import json
def hello(request):
return HttpResponse('Hello, World!')
def req_count(request):
# TODO: Update the amount of requests the "reqcount" url has gotten, then return it
with open('..\\data.json', 'w+') as f:
data = json.load(f)
data['views']['reqcount']['reqs'] += 1
json.dump(data)
return HttpResponse(data['views']['reqcount']['reqs'])
ПРИМЕЧАНИЯ:
- Я использую Windows 10
- Я использую Python 3.8
- Я использую pipenv 2021.5.29
- Я использую Django 3.2.6
- Я не получаю никаких ошибок при запуске моего веб-сервера, выполнив "py manage.py runserver"
Я не мог комментировать, чтобы запросить больше информации из-за низких очков репутации (менее 50)
Я думаю, что проблема в том, что если ваш JSON файл пуст и вы пытаетесь прочитать его, вы получите JSONDecodeError
, но не в том случае, если в файле есть действительные JSON данные. При использовании w+
вы получите ту же ошибку, даже если в файле есть действительные данные JSON, потому что он очищает содержимое файла (или, скорее, перезаписывает его) до выполнения каких-либо действий.
Решением, которое я могу придумать, является создание 2 функций для чтения и обновления атрибута reqs
.
Предполагая, что файл JSON не пуст, вы можете получить что-то вроде этого:
file.json
{
"views": {
"reqcount": {
"reqs": 1
}
}
}
def read_json_file(filename):
"""
read data from json file
return: dict
"""
with open(filename, "a+") as file: # use a+ to deal with the case where the file does not exist
data = json.load(file)
return data
def update_json_file(filename, data):
""" update the json file by changing the 'reqs` count """
with open(filename, "w+") as file:
data['views']['reqcount']['reqs'] += 1
file.write(json.dumps(data))
return data
Затем вы можете вызывать эти функции внутри представления e.g
def req_count(request):
# TODO: Update the amount of requests the "reqcount" url has gotten, then return it
data = read_json_file("file.json")
updated_data = update_json_file("file.json", data)
return HttpResponse(updated_data['views']['reqcount']['reqs'])
Таким образом, при каждом вызове представления счетчик будет обновляться.