Django视图转JSON传模板报错:date类型无法JSON序列化
Django序列化Model数据到JSON时日期不可序列化错误的解决方案
问题场景
在Django的views.py中尝试将resource模型数据序列化为JSON,传递到模板供JavaScript使用时触发错误:
Object of type date is not JSON serializable
涉及代码
models.py
class resource(models.Model): title=models.CharField(max_length=100) size=models.CharField( max_length=20, default="") desc=models.TextField(default="") file=models.FileField(default="", blank=True) url= models.URLField(max_length=200, blank=True) varient=models.CharField(max_length=100, default="") Brand = models.ForeignKey(brand,on_delete=models.CASCADE, default="") Model = models.ForeignKey(model,on_delete=models.CASCADE, default="") Categories = models.ForeignKey(category,on_delete=models.CASCADE, default="") update_at=models.DateField(auto_now=True) paymentvarified=models.BooleanField(default=False) slug=models.SlugField(default="", unique=True, blank=True) Tags = TaggableManager(blank=True)
views.py(错误写法)
data={ 'limitjsondata':json.dumps(list(resource.objects.values())), 'get_pro':get_pro, 'Resource':Resource, 'pro_member':pro_members, } return render(request, 'firmApp/download.html', data)
错误原因
resource.objects.values()返回的字典中,update_at字段是Python原生date对象,而标准库json.dumps()无法直接序列化日期类型对象,因此触发报错。
解决方案
方法1:使用Django自带序列化器
Django内置的序列化工具可自动处理日期等Django字段类型,无需手动转换:
from django.core import serializers # 替换原json.dumps部分 resource_data = serializers.serialize('json', resource.objects.all()) data={ 'limitjsondata': resource_data, 'get_pro':get_pro, 'Resource':Resource, 'pro_member':pro_members, } return render(request, 'firmApp/download.html', data)
注意:该方式返回的JSON结构包含model、pk、fields三层,前端JS需通过obj.fields.update_at访问日期字段。
方法2:自定义JSON编码器
若想保留values()的字典结构,可自定义编码器将日期转为字符串:
import json from datetime import date class DateEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, date): return obj.isoformat() return super().default(obj) # 使用自定义编码器序列化数据 resource_values = list(resource.objects.values()) data={ 'limitjsondata': json.dumps(resource_values, cls=DateEncoder), 'get_pro':get_pro, 'Resource':Resource, 'pro_member':pro_members, } return render(request, 'firmApp/download.html', data)
方法3:查询时手动转换日期字段
通过Django数据库函数,在查询阶段直接将日期字段转为字符串:
from django.db.models.functions import Cast from django.db.models import CharField resource_values = list(resource.objects.values( 'title', 'size', 'desc', 'url', 'varient', 'Brand', 'Model', 'Categories', 'paymentvarified', 'slug', update_at=Cast('update_at', output_field=CharField()) )) data={ 'limitjsondata': json.dumps(resource_values), 'get_pro':get_pro, 'Resource':Resource, 'pro_member':pro_members, } return render(request, 'firmApp/download.html', data)
内容的提问来源于stack exchange,提问作者Malik Naveed
相关产品推荐
相关产品推荐

