gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 21:17:18 25 4
gpt4 key购买 nike

为了开发自定义 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com