python - Django Rest Framework - 在空值上调用 serializer.to_internal_value
问题描述
我正在尝试为传递null
给自定义.to_internal_value
方法的 django API 编写字段序列化器。
我的用例是用于datetime
构成时间范围的两个字段。我希望我的 API 的用户能够"start_dt": null
在 PUT/POST/PATCH 请求中给我一些东西,并让我的序列化程序将其转换为datetime.datetime.min
(或者,在 , 的情况下end_dt
)datetime.datetime.max
。
这是我到目前为止所拥有的。我能够使用该方法使Object->JSON
序列化正常工作(转换datetime.min
和datetime.max
值到None
) - 但是在转换时.to_representation(self, value)
它似乎没有调用- 而是在两个字段之一被指定为时传递到我的逻辑的其余部分。.to_internal_value(self, value)
null->None
None
null
import pytz
from datetime import datetime
UTC = pytz.timezone("UTC")
max_dt = UTC.localize(datetime.max)
min_dt = UTC.localize(datetime.min)
class CustomDateTimeField(serializers.Field):
def __init__(self, *args, **kwargs):
self.datetime_field = fields.DateTimeField()
self.infinity_direction = kwargs.pop('infinity_direction', None)
if not (self.infinity_direction == '+' or self.infinity_direction == '-'):
raise AssertionError("Expected CustomDateTimeField to be created with `infinity_direction` equal to either '+' or '-'")
super().__init__(*args, **kwargs)
def to_representation(self, value):
"""
Represent both MAX and MIN times as None/'null'
Else return a normal datetime string
"""
if value == min_dt or value == max_dt:
return None
return self.datetime_field.to_representation(value)
def to_internal_value(self, value):
"""
Translate None/'null' values to either MAX or MIN - depending on self.infinity_direction
Else return a normal datetime object
"""
if value == None:
return max_dt if self.infinity_direction == '+' else min_dt
return self.datetime_field.to_internal_value(value)
在我的模型的序列化程序中,我使用了这些字段,例如...
class TimeRangeSerializer(serializers.ModelSerializer):
start_dt = CustomDateTimeField(infinity_direction='-', allow_null=True)
end_dt = CustomDateTimeField(infinity_direction='+', allow_null=True)
class Meta:
model = TimeRange
fields = ('id', 'start_dt', 'end_dt')
提供更多示例...
EX 1: 发布这个
{}
给出以下正确的返回值
{
"end_dt": [
"This field is required."
],
"start_dt": [
"This field is required."
]
}
例 2:
发布这个
{
"start_dt": null,
"end_dt": null
}
CustomDateTimeField.to_internal_value
永远不会被调用 - 并被start_dt
传递end_dt
给我的对象的创建None
,而不是期望的datetime.min
和datetime.max
值。
例 3:
发布这个
{
"start_dt": "2018-08-28T00:00:00Z",
"end_dt": null
}
似乎调用to_internal_value
- 但仅限于start_dt
(它正确解析为日期时间对象)。它不调用to_internal_value
.null
解决方案
更改您的代码如下:
def to_internal_value(self, value):
"""
Translate None/'null' values to either MAX or MIN - depending on self.infinity_direction
Else return a normal datetime object
"""
return self.datetime_field.to_internal_value(value)
def validate_empty_values(self, data):
(is_empty_value, data) = super(CustomDateTimeField, self).validate_empty_values(data)
if is_empty_value and data is None:
return is_empty_value, max_dt if self.infinity_direction == '+' else min_dt
return is_empty_value, data
to_interval_value
如果字段的值为空,则drf 永远不会调用该字段。
推荐阅读
- summary - 如何在我自己的 wikidata 中拥有摘要 API
- ios - 如何使用 alamofire 使用 get 方法构建 url 请求
- azure - EventHubClient 多久打开一次 AMQP 连接?
- elixir - 如何从 Emun(元组)中拆分值并将其相邻插入(两半)
- azure - 使用 SSIS 从 ADLS gen 2 读取
- dropbox - 如何在 Dropbox 中获取文件的完整路径或 URL?
- laravel - 返回 url 中的其他条目也包括第一个条目
- elixir - 我不明白为什么我的第一个 Elixir 脚本失败了
- ruby-on-rails - 多选与选择
- r - 从需要用户名和密码的静态 IP 设备(Windows 或 Mac)下载相同的文件