Skip to main content
 首页 » 编程设计

python之在 Django 中定义自定义模型字段的覆盖方法

2025年05月04日43sky-heaven

我一直在尝试在 python 中定义自定义 django 模型字段。我在以下位置引用了 Django 文档 https://docs.djangoproject.com/en/1.10/howto/custom-model-fields/ .但是,我对以下方法感到困惑(我根据我的理解将其分为几组):-

第 1 组(根据文档,该组中的方法相互关联)

  1. __init__()
  2. 解构()

第 2 组

  1. 数据库类型()
  2. rel_db_type()
  3. get_internal_type()

第 3 组

  1. from_db_value()
  2. to_python()
  3. get_prep_value()
  4. get_db_prep_value()
  5. get_db_prep_save()
  6. value_from_object()
  7. value_to_string()

第 4 组

  1. 表单域

我有以下问题:-

  1. 什么时候使用deconstruct()? Docs says that, it's useful during migration,但没有明确解释。而且,什么时候叫?

  2. db_type() 和 get_internal_type() 的区别

  3. get_prep_value() 和 get_db_prep_value() 的区别
  4. value_from_object() 和 value_to_string() 之间的区别。 value_from_object() 未在文档中给出。
  5. from_db_value()、value_to_string() 和 to_python() 都从字符串中给出 python 对象。那么,为什么会存在这些不同的方法?

我知道,我问了一个有点冗长的问题。但找不到任何其他方式来更好地提出这个问题。

提前致谢。

请您参考如下方法:

我会尽力回答他们:

问:什么时候使用deconstruct()?

A: 当您拥有 Field 的实例以根据您刚刚传入 __init__ 的参数重新创建它时,将使用此方法>。 正如他们在 docs 中提到的那样,如果您在 __init__ 方法中将 max_length arg 设置为静态值;您的实例不需要它。所以你可以在你的 deconstruct() 方法中删除它。这样,当您在模型中使用 max_length 时,它就不会出现在您的实例中。您可以将 deconstruct 视为在模型中使用您的字段之前的最后清理和控制位置。


问db_type()和get_internal_type()的区别

答:两者有关联,但属于不同层次。

如果您的自定义字段的数据类型取决于您使用的数据库,db_type() 是您可以进行控制的地方。同样,就像他们在 docs 中提到的那样,如果你的字段是一种日期/时间值,你应该/可以检查当前数据库是 PostgreSQL 还是 MySQL 在此方法中。因为日期/时间值在 PostgreSQL 中称为 timestamp,而在 MySQL 中称为 datetime。

get_internal_type 方法是 db_type() 的高级版本。让我们回顾一下日期/时间值示例:如果您不想检查和控制属于不同数据库的每个数据类型,您可以从 built-in Django 字段继承自定义字段的数据类型。而不是检查它是否应该是 datetime 或 timestamp;您可以在 get_internal_type 方法中简单地返回 DateField。正如他们在 docs 中提到的那样, 如果您已经创建了db_type 方法,在大多数情况下,您不需要get_internal_type 方法。


问get_prep_value()和get_db_prep_value()的区别

答:这些家伙还在 db_type() 和 get_internal_type() 之间共享几乎相同的逻辑。首先,这两种方法都代表将 db 值转换为 python 对象。但是,就像在 db_type 方法中一样,get_db_prep_value() 代表 backend 特定字段类型。


问value_from_object() 和value_to_string() 的区别。 value_from_object() 没有在文档中给出

答: 来自文档:

To customize how the values are serialized by a serializer, you can override value_to_string(). Using value_from_object() is the best way to get the field’s value prior to serialization.

所以,实际上我们不需要记录的value_from_object。此方法用于在序列化之前获取字段的原始值。使用此方法获取值,并自定义如何在 value_to_string 方法中对其进行序列化。他们甚至在 docs 中放了一个示例代码


问: from_db_value()、value_to_string() 和 to_python() 都从字符串中给出 python 对象.那么,为什么会存在这些不同的方法?

A: to_python() 将字段值转换为有效的 python 对象,value_to_string() 将字段值转换为您自定义的字符串序列化。它们代表不同的工作。

而from_db_value将数据库返回的值转换为python对象。实际上从未听说过。但是检查this part来自文档:

This method is not used for most built-in fields as the database backend already returns the correct Python type, or the backend itself does the conversion.