我一直在尝试在python中定义自定义django模型字段。我在以下位置https://docs.djangoproject.com/en/1.10/howto/custom-model-fields/引用了django文档。但是,我对以下方法感到困惑(根据我的理解,我将其分成了几组): -
第1组(该组中的方法按照文档相互关联)
__init__
()第2组
第3组
第4组
我有以下问题: -
何时使用deconstruct()
? Docs说,它在迁移过程中很有用,但是没有明确解释。什么时候叫它?
db_type()
和get_internal_type()
get_prep_value()
和get_db_prep_value()
value_from_object()
和value_to_string()
之间的差异。文档中未提供value_from_object()
。from_db_value()
,value_to_string()
和to_python()
都会从字符串中提供python对象。那么,为什么存在这些不同的方法?我知道,我问了一个冗长的问题。但找不到任何其他方式来更好地提出这个问题。
提前致谢。
答案 0 :(得分:5)
我会尽力回答:
问:使用deconstruct()
时
答:当您的Field
实例根据您在__init__
中传递的参数重新创建时,会使用此方法。
正如他们在docs中提到的,如果您在max_length
方法中将__init__
arg设置为静态值;你的实例不需要它。因此,您可以在deconstruct()
方法中将其删除。这样,当您在模型中使用max_length
时,deconstruct
将不会显示在您的实例中。在模型中使用字段之前,您可以将db_type()
视为最后一个清理和控制位置。
问: get_internal_type()
和db_type()
A:它们都是相关的,但属于不同的级别。
如果您的自定义字段的数据类型取决于您使用的是哪个数据库,则 PostgreSQL
就是您可以执行控件的地方。同样,就像他们在docs中提到的那样,如果您的字段是一种日期/时间值,您应该/可以在此方法中检查当前数据库是MySQL
还是timestamp
。因为PostgreSQL
中的日期/时间值称为datetime
,而MySQL
中称为get_internal_type
。
db_type()
方法是built-in
的更高级别版本。让我们来看看日期/时间值示例:如果您不想检查和控制属于不同数据库的每个数据类型,您可以从datetime
Django字段继承自定义字段的数据类型。而不是检查它应该是timestamp
还是DateField
;您只需在get_internal_type
方法中返回db_type
即可。正如他们在docs中提到的,如果您已经创建了get_internal_type
方法,那么在大多数情况下,您不需要get_prep_value()
方法。
问: get_db_prep_value()
和almost
A:这些家伙在db_type()
和get_internal_type()
之间也有python objects
个相同的逻辑。首先,这两种方法都代表将db值转换为db_type
。但是,与get_db_prep_value()
方法一样,backend
代表value_from_object()
特定字段类型。
问: value_to_string()
和value_from_object()
之间的差异。文档中未提供value_to_string()
答:来自文档:
要自定义序列化程序如何序列化值,您可以 覆盖
value_from_object()
。使用value_from_object
是最好的方法 在序列化之前获取字段的值。
所以,实际上我们不需要记录value_to_string
。此方法用于在序列化之前获取字段的原始值。使用此方法获取值,并自定义如何在from_db_value()
方法中序列化它。他们甚至在docs
问: value_to_string()
,to_python()
和to_python()
都会从字符串中提供python对象。那么,为什么存在这些不同的方法呢?
A:当value_to_string()
将字段值转换为有效的python对象时,from_db_value
会将字段值转换为自定义序列化的字符串。他们代表着不同的工作。
并且private Map<String, Callable<Integer>> timeUnitsMap = new HashMap<String, Callable<Integer>>(){
{timeUnitsMap.put("minutes", () -> call());}};
将数据库返回的值转换为python对象。从来没有听说过它。但请从文档中查看this part:
此方法不用于大多数内置字段作为数据库 后端已经返回正确的Python类型或后端本身 进行转换。