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'])

Таким образом, при каждом вызове представления счетчик будет обновляться.

Вернуться на верх