如何让 Django Rest Framework DateTimeField 需要时区信息?

How do I get a Django Rest Framework DateTimeField to require timezone information?

我有一个带有 DateTimeField 的 Django Rest Framework 序列化程序。默认情况下,它将使用 iso-8601 格式反序列化 date/time 值。但是,iso-8601 不需要时区偏移量。我需要用户始终提供一些时区偏移信息(或者更好地说,再次验证 rfc 3339,iso-8601 的一个子集)。

该字段允许您设置 input_formats 的自定义列表,但由于 Python 无法正确解析 rfc 3339 格式的日期(即小时和分钟部分之间带有冒号的偏移量不受支持)我卡住了。

Django Rest Framework 中的 DateTimeField 完全能够解析 rfc 3339 日期时间值,这要归功于它使用了 django.utils.dateparse.parse_datetime(它有点宽松,但没关系)。

parse_datetime returns 可识别时区的日期时间实例(具有固定偏移量的 tzinfo zet)或简单的日期时间实例(无 tzinfo)。

Django Rest Framework 的 DateTimeField 将任何给定值转换为感知日期时间值,如果设置了 settings.USE_TZ 或者字段被赋予了 default_timezone 参数的值,否则任何值都被设为天真。

DateTimeField的enforce_timezone方法负责取值aware/naive.

知道这一点,如果解析的日期时间值是天真的,则可以通过覆盖 enforce_timezone 并引发 ValidationError 来强制解析的值必须是时区感知的:

from django.utils import timezone

class DateTimeFieldWithOffset(serializers.DateTimeField):
    default_error_messages = {
        'naive': 'Datetime value is missing a timezone offset.'
    }

    def enforce_timezone(self, value):
        if timezone.is_naive(value):
            self.fail('naive')
        return super().enforce_timezone(value)