用于在django

时间:2016-12-18 06:59:02

标签: python django django-models django-model-field

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

第1组(该组中的方法按照文档相互关联)

  1. __init__()
  2. 解构()
  3. 第2组

    1. db_type()
    2. rel_db_type()
    3. get_internal_type()
    4. 第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()
      8. 第4组

        1. formfield
        2. 我有以下问题: -

          1. 何时使用deconstruct()? Docs说,它在迁移过程中很有用,但是没有明确解释。什么时候叫它?

          2. db_type()get_internal_type()

          3. 之间的差异
          4. get_prep_value()get_db_prep_value()
          5. 之间的差异
          6. value_from_object()value_to_string()之间的差异。文档中未提供value_from_object()
          7. from_db_value()value_to_string()to_python()都会从字符串中提供python对象。那么,为什么存在这些不同的方法?
          8. 我知道,我问了一个冗长的问题。但找不到任何其他方式来更好地提出这个问题。

            提前致谢。

1 个答案:

答案 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类型或后端本身   进行转换。