更改Python中默认的日期打印格式

2 投票
1 回答
608 浏览
提问于 2025-04-16 00:31

我可以改变 datetime.datetime 对象的默认 __str__() 函数吗?默认情况下,它返回的格式像是 '2010-06-28 12:43:56.985790',而我需要它打印成 '2010-06-28T12:44:21.241228' 这样的格式(这就是 isoformat() 函数的效果)。

我需要这样做是为了将 Django 模型序列化成 JSON 格式。

我的模型是:


class Transport(models.Model):
    user = models.ForeignKey(User)
    source = models.ForeignKey(Marker, related_name="source_marker")
    destination = models.ForeignKey(Marker, related_name="destination_marker")
    object = models.CharField(choices=possesion_choices, max_length=2**6)
    quantity = models.IntegerField()
    time_sent = models.DateTimeField()
    time_arrived = models.DateTimeField()

当我使用 wadofstuff 模块 进行序列化时,它打印出来的格式像是


print serializers.serialize('json', Transport.objects.all(), relations=('source', 'destination',)  indent=4)
[
    {
        "pk": 1, 
        "model": "main.transport", 
        "fields": {
            [.. bla bla ..]
            "time_sent": "2010-06-28 12:18:05", 
            "time_arrived": "2010-06-28 12:38:36", 
            [.. bla bla ..]
        }
    }
]

1 个回答

3

Django在序列化的时候,会用一个字段的value_to_string方法来生成字符串表示。所以你可以定义一个自定义字段的子类,重写这个方法:

class MyDateTimeField(DateTimeField)
    def value_to_string(self, obj):
        val = self._get_val_from_obj(obj)
        if val is None:
            data = ''
        else:
            data = val.isoformat()
        return data

编辑过

哎呀,看起来我之前找错地方了。其实serializers.python.Serializer.handle_field这个方法会检查日期时间字段,并且直接把它们传给JSON编码器,没有做任何改变。所以我们真正需要重写的是这个编码器。

class MyJSONEncoder(DjangoJSONEncoder):
    def default(self, o):
        if isinstance(o, datetime.datetime):
            return o.isoformat()
        else:
            return super(MyJSONEncoder, self).default(o)

不幸的是,wadofstuff把原来的DjangoJSONEncoder写死了,所以我们也需要重写序列化器。

from wadofstuff.django.serializers.json import Serializer
class BetterSerializer(Serializer):
    """
    Convert a queryset to JSON.
    """
    def end_serialization(self):
        """Output a JSON encoded queryset."""
        self.options.pop('stream', None)
        self.options.pop('fields', None)
        self.options.pop('excludes', None)
        self.options.pop('relations', None)
        self.options.pop('extras', None)
        simplejson.dump(self.objects, self.stream, cls=MyJSONEncoder,
            **self.options)

撰写回答