python - Django "deconstruct"模型字段函数的用途是什么?

标签 python django

为了开发自定义 Django 模型字段,我正在阅读文档。

我已经开发了我的自定义字段(这几乎等于示例的自定义字段,HandField:一个映射到 Python 类的字段......唯一的区别是我继承自 models.CharField 而不是 models.Field)。

from external_library import ExternalClass

class ExternalClassField(models.CharField):
    description = "An ExternalClass field"

    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = 14
        super(ExternalClassField, self).__init__(*args, **kwargs)

    def from_db_value(self, value, expression, connection, context):
        if value is None:
            return value
        return ExternalClass(value)

    def to_python(self, value):
        if isinstance(value, ExternalClass):
            return value

        if value is None:
            return value

        return ExternalClass(value)

    def get_prep_value(self, value):
        if value is None:
            return value

        if isinstance(value, ExternalClass):
            return value.to_string()

        return value

该字段的行为符合预期。但是,我停留在文档的这一部分:deconstruct()功能。

特别是,我不明白的是:

  • 解构函数的具体用途是什么?
  • 为什么即使没有它(即使我修改了 init 参数)我的字段也能完美运行?
  • Django 如何以及何时调用 deconstruct 函数?

我不想盲目复制粘贴我看不懂的代码,但文档也不清楚。

最佳答案

deconstruct() 方法用于帮助执行系统无法自动处理的模型迁移。让我们来看一个 deconstruct 被调用的场景。

假设我们有一些模型,我们向它添加了一个自定义字段。我们尝试使用 python manage.py makemigrations 进行迁移。

我们遇到以下错误:

ValueError: Cannot serialize: Foo
There are some values Django cannot serialize into migration files.

原来已经有a related ticket了已提交给 Django 项目,让我们检查一下。

ticket-issue

其中一位核心开发人员回应说这是有意为之的行为,因为我们的字段包含一个可调用对象。

ticket-resolution

因此,我们在文档中遗漏了一些内容。存储了一个可调用值,但由于某种原因无法自动迁移。我们能做什么?

嗯,除了告诉我们有关 ValueError 的信息,manage.py 还为我们提供了一个有用的文档链接:

docs-link

进入该页面后,向下滚动一点,直到我们到达关于 serializing values 的部分.

Django can serialize the following:

  • ...
  • Anything with a custom deconstruct() method (see below)
  • ...

好吧,让我们see below :

You can let Django serialize your own custom class instances by giving the class a deconstruct() method. It takes no arguments, and should return a tuple of three things (path, args, kwargs):

  • path should be the Python path to the class, with the class name included as the last part (for example, myapp.custom_things.MyClass). If your class is not available at the top level of a module it is not serializable.
  • args should be a list of positional arguments to pass to your class’ init method. Everything in this list should itself be serializable.
  • kwargs should be a dict of keyword arguments to pass to your class’ init method. Every value should itself be serializable.

请注意,如文档所述,deconstruct() 方法与 __eq__() 协同工作:

To prevent a new migration from being created each time makemigrations is run, you should also add a __eq__() method to the decorated class. This function will be called by Django’s migration framework to detect changes between states.

在我的例子中,错误是在一个不应该被调用的值之后添加了括号,但在许多情况下,你会想要为迁移实现解构方法。 (这是另一个有例子的 useful link。)

关于python - Django "deconstruct"模型字段函数的用途是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34558397/

相关文章:

python - Pandas:用具有相同固定重复次数的数据帧填充固定数量的新列

python - Scikit-learn:权重在岭回归中的作用

python - 在哪里可以将保存确认页面连接到 Django 管理员? (类似删除确认)

python - 使用一个大的 INSERT 语句保存许多 Django 对象

javascript - 在 HTML 中用一条线连接 2 个图像。 Django 模板

python - 如何使用 R studio 导入 Pandas

python - 如何在python中的子流程中使用错误处理

python BeautifulSoup解析表

python - IDM FIWARE Django 服务器超时

python - 找不到 '' 的反向。 '' 不是有效的 View 函数或模式名称