Django使用JSON实现请求计数器出现JSONDecodeError报错如何解决
问题原因分析
第一次报错原因
- 你使用
w+模式打开文件:w+模式的特性是打开文件时直接清空所有内容,执行json.load(f)时文件已经为空,JSON解析空内容就会抛出该错误 - 代码中
json.dump(data)没有传入目标文件对象作为第二个参数,就算前面解析成功也无法将数据写入文件
第二次修改后报错原因
- 你使用
a+模式打开文件,该模式下文件指针默认指向文件末尾,直接调用f.read()读取到的是空字符串,JSON解析空字符串就会触发line 1 column 1 (char 0)的错误 - 没有使用绝对路径,Django运行时工作目录是
manage.py所在的根目录,相对路径容易出现找不到文件的问题
解决步骤
- 首先在Django项目根目录(和
manage.py同目录的位置)新建data.json文件,写入符合你代码结构的初始内容:
{ "views": { "reqcount": { "reqs": 0 } } }
- 修改
views.py的代码,使用绝对路径定位文件,修正文件读写逻辑:
from django.shortcuts import render from django.http import HttpResponse from django.conf import settings import json def hello(request): return HttpResponse('Hello, World!') def req_count(request): # 用BASE_DIR拼出data.json的绝对路径,避免路径错误 json_path = settings.BASE_DIR / 'data.json' # 只读模式读取现有数据 with open(json_path, 'r', encoding='utf-8') as f: data = json.load(f) # 修改计数 data['views']['reqcount']['reqs'] += 1 # 写入模式更新文件内容 with open(json_path, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) return HttpResponse(data['views']['reqcount']['reqs'])
如果需要兼容文件不存在/格式错误的场景,可以添加异常处理逻辑:
def req_count(request): json_path = settings.BASE_DIR / 'data.json' # 初始化默认数据 default_data = {"views": {"reqcount": {"reqs": 0}}} try: with open(json_path, 'r', encoding='utf-8') as f: data = json.load(f) except (FileNotFoundError, json.JSONDecodeError): data = default_data data['views']['reqcount']['reqs'] += 1 with open(json_path, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) return HttpResponse(data['views']['reqcount']['reqs'])
额外提示:该方案仅适合本地测试使用,生产环境高并发场景下,多请求同时读写JSON文件会出现数据错乱、文件损坏的问题,建议使用Redis或者数据库存储计数。
内容的提问来源于stack exchange,提问作者Crabby Fish
相关产品推荐
相关产品推荐

