Django查询过滤结果时如何转换DateField字段?
问题描述
我在Django中定义了如下模型:
# models.py class Activity(models.Model): name = models.CharField(max_length=50) date_created = models.DateField()
创建实例的方式为:
from datetime import date Activity.objects.create(name="Foo", date_created=str(date.today()))
已知可以通过auto_now_add=True自动存储日期,但当前无法修改模型结构,必须基于现有模型解决问题。使用.values()查询过滤后的实例时出现JSON序列化错误:
activity = Activity.objects.filter(name="soccer").values()
错误信息:
TypeError: Object of type date is not JSON serializable
需求是在.values()查询时格式化date_created字段,避免序列化报错。
解决方案
方法1:Python层面手动格式化
拿到.values()的结果后,遍历将date对象转为字符串,这种方法不依赖数据库类型,兼容性强:
# views.py activities = list(Activity.objects.filter(name="soccer").values()) for activity in activities: # 按需求指定日期格式,比如'%Y-%m-%d' activity['date_created'] = activity['date_created'].strftime('%Y-%m-%d')
方法2:数据库层面通过注解格式化
利用Django的数据库函数在查询时直接将日期转为字符串,不同数据库需对应不同函数:
MySQL/MariaDB
使用DATE_FORMAT函数:
from django.db.models import Func, Value, CharField activities = Activity.objects.filter(name="soccer").annotate( formatted_date=Func( 'date_created', Value('%Y-%m-%d'), function='DATE_FORMAT', output_field=CharField() ) ).values('name', 'formatted_date')
PostgreSQL
使用TO_CHAR函数:
from django.db.models import Func, Value, CharField activities = Activity.objects.filter(name="soccer").annotate( formatted_date=Func( 'date_created', Value('YYYY-MM-DD'), function='TO_CHAR', output_field=CharField() ) ).values('name', 'formatted_date')
SQLite
使用strftime函数:
from django.db.models import Func, Value, CharField activities = Activity.objects.filter(name="soccer").annotate( formatted_date=Func( Value('%Y-%m-%d'), 'date_created', function='strftime', output_field=CharField() ) ).values('name', 'formatted_date')
方法3:使用Django REST Framework序列化(若项目已用DRF)
通过Serializer自动处理日期格式,适合API场景:
from rest_framework import serializers class ActivitySerializer(serializers.ModelSerializer): # 指定日期格式,或用format='iso-8601'遵循标准格式 date_created = serializers.DateField(format='%Y-%m-%d') class Meta: model = Activity fields = ['name', 'date_created'] # 查询并序列化 activities = Activity.objects.filter(name="soccer") serialized_data = ActivitySerializer(activities, many=True).data
注:报错原因是
.values()返回的QuerySet中,date_created是Python原生date对象,JSON序列化器无法直接处理这类对象,因此需要转为字符串格式。
内容的提问来源于stack exchange,提问作者gerdo smith
相关产品推荐
相关产品推荐

