我想创建一个自定义字段,接收日期时间字符串并将数据存储在两个db列中。我正在阅读django doc,但不知道如何使用多个db列。
这是一个旧的数据库,所以我不能改变数据库表的布局。
我现在就有这个模型。
class MyModel(models.Model):
mixing_datetime = models.DateTimeField()
mixing_datetime_utc_offset_seconds = models.IntegerField()我想创建一个字段,让前端(它是一个带有DRF的API )只发送一个日期时间字符串(而不是单独发送日期时间和偏移量),并让后端在后台完成工作。所以我们的想法是:
class MyModel(models.Model):
mixing_datetime = models.DateTimeField()
mixing_datetime_utc_offset_seconds = models.IntegerField()
datetime = MyCustomDatetimeField() # This also should not be sent to db所以,为了澄清,我们的想法是让前端来做这个请求:
frontend_client.post('server_url', payload={'datetime': '2021-07-02T14:34:49+00:00'}然后在后端执行一些钙化操作,并同时设置mixing_datetime和mixing_datetime_utc_offset_seconds
我怎样才能做到这一点?
发布于 2021-07-07 01:50:18
因此,我最终提出了这个解决方案。这不是我所要求的( django模型的自定义字段),但因为它是我正在做的API,所以我决定做一个DRF序列化程序自定义字段。如果你不使用DRF,也许你可以重写model的save方法。
这是DRF序列化程序自定义字段。
class CustomDateTimeField(serializers.Field):
"""Custom field used to convert a string in isoformat into other two fields.
So the caller instead of sending datetime and offset, will only send the string, and internally we
are going to split it in the two respective fields.
Same when caller requests data, it will receive only one datetime field. (output pf to_representation).
In a model we are going to have two fields that will follow this naming pattern:
>> datetime = models.DateTimeField()
>> offset_seconds = models.IntegerField()
"""
def __init__(self, **kwargs):
self.prefix_field_name = kwargs.pop("prefix_field_name")
self.datetime_field = 'datetime'
self.offset_seconds_field = 'offset_seconds'
super().__init__(**kwargs)
# Set this, so we receive all model fields in to_representation.
self.source = '*'
def to_representation(self, instance):
"""This function is called when an object instance is serialized. For example an instance retrieved from db.
For example this serialization will lead into this function:
>> instance = MyModel.objects.last()
>> MyModelSerializer(instance).data
"""
return get_isoformat_string_from_datetime(
getattr(instance, self.datetime_field), getattr(instance, self.offset_seconds_field)
)
def to_internal_value(self, data):
"""This functions is called when a json object is serialized. For example on an Api call.
The data returned from this function will be used to update the 'validated_data' dictionary.
For example:
>> data_to_be_serialized = {'datetime': '2021-04-10T07:51:15.958266-01:00', 'other_field': 10}
>> MyModelSerializer(data=data_to_be_serialized)
"""
if not isinstance(data, str):
raise serializers.ValidationError("Incorrect type. Expected a string")
if not is_in_isoformat(data):
raise serializers.ValidationError("Data should be in isoformat")
datetime = get_datetime_from_string(data)
# This fields are going to be used to update validated_data dict.
ret = {
self.datetime_field: datetime,
self.offset_seconds_field: get_utc_offset_seconds(datetime),
}
return ret用法:
class TestModel(models.Model):
datetime = models.DateTimeField()
offset_seconds = models.IntegerField()
class MyModelSerializer(serializers.ModelSerializer):
datetime = CustomDateTimeField()
class Meta:
model = TestModel
fields = ('datetime', )https://stackoverflow.com/questions/68214059
复制相似问题