Django 3.0a+Python3.7下SQLite兼容JSON字段报错解决咨询
嘿,我来帮你搞定这个问题!你遇到的ImportError: cannot import name 'six' from 'django.utils'是因为Django 3.0开始彻底移除了django.utils.six模块——这个模块本来是用来兼容Python2和Python3的,而Django3.0起只支持Python3,所以那些还依赖six的第三方jsonfield库自然就报错了。下面给你几个实用的解决办法:
方案1:升级到Django 3.1+(最推荐,省心省力)
Django 3.1及以后版本把JSONField从PostgreSQL专属的django.contrib.postgres.fields移到了通用的django.db.models里,原生支持SQLite、MySQL、PostgreSQL等主流数据库,完全不需要第三方库。
首先升级Django:
pip install --upgrade django>=3.1
然后在你的模型里直接用官方原生的字段:
from django.db import models class YourModel(models.Model): # 可以设置默认值为空字典,避免null问题 json_data = models.JSONField(default=dict)
官方维护的字段,兼容性和稳定性拉满,还支持数据库层面的JSON查询(比如PostgreSQL的jsonb操作),绝对是首选方案。
方案2:手动修复第三方库的six依赖(适合暂时不想升级Django的情况)
如果你因为某些原因没法升级Django,可以手动修改你用的第三方jsonfield库的代码,把所有six的引用替换成Python3原生语法:
- 找到库的安装路径(比如你这里是
C:\Program Files (x86)\Python37-32\lib\site-packages\下对应的库文件夹) - 打开所有导入
six的文件,删掉from django.utils import six这行 - 替换常见的
six用法:six.text_type→strsix.string_types→(str,)six.iteritems(obj)→obj.items()(Python3里字典的items()本身就是迭代器)six.integer_types→(int,)
改完之后,库就能在Django3.0下正常工作了。不过要注意,以后升级这个库的时候,需要重新做一遍修改,有点麻烦。
方案3:自定义兼容多数据库的JSON字段(适合简单场景)
如果上面两个方法都不符合你的需求,你可以自己写一个轻量的自定义字段,本质是把JSON序列化成字符串存在TextField里,所有支持TextField的数据库都能用:
from django.db import models import json class CustomJSONField(models.TextField): def from_db_value(self, value, expression, connection): # 从数据库读取时反序列化 if value is None: return {} try: return json.loads(value) except ValueError: return value def to_python(self, value): # 转换为Python对象 if isinstance(value, dict): return value if value is None: return {} try: return json.loads(value) except ValueError: return value def get_prep_value(self, value): # 存入数据库时序列化 if value is None: return None return json.dumps(value)
然后在模型里使用这个字段:
class YourModel(models.Model): json_data = CustomJSONField(default=dict)
这个方法的缺点是不支持数据库层面的JSON查询(比如没法用PostgreSQL的jsonb筛选),但如果你的业务不需要复杂的JSON操作,完全够用。
内容的提问来源于stack exchange,提问作者Allon

