Django 打字提示

ela*_*ver 5 django django-migrations

我创建了一个空迁移,现在看起来像这样:

def forwards(apps, schema_editor):
    Foo = apps.get_model('app', 'Foo')
    FixedResponse.objects.create(name='Bar')


def backwards(apps, schema_editor):
    Foo = apps.get_model('app', 'Foo')
    Foo.objects.filter(name='Bar').delete()


class Migration(migrations.Migration):

    dependencies = [
        ('app', '0035_fixedresponse'),
    ]

    operations = [
        migrations.RunPython(forwards, backwards)
    ]
Run Code Online (Sandbox Code Playgroud)

由于没有关于此主题(特定于迁移)或最佳实践的 Django 文档,

我想知道如何输入提示上面的代码?

Ant*_*ard 7

这个问题没有通用的答案,您能找到的唯一有信誉的来源是 Django 的参考文档,其中没有提及任何有关迁移的注释。

\n

“在 Django 中处理类型提示的正确方法”严格取决于您公司的政策。在问如何之前,你必须先问为什么。一旦知道了原因,找出方法就很简单了。然而,如果不是问“为什么?” ,你(或你的老板)问“为什么不呢?” ,这就把问题颠倒过来了。做某事需要理由,但不做某事不需要理由。(1)

\n

如果理由是“通过CI”,那么这不是正当理由。CI 的目的是为你工作,而不是相反。

\n

如果原因是“记录代码”,那么这也不是有效的理由。类型提示文档,编写文档的目的不是“记录代码”。为什么需要任何文档?谁将阅读此文档?他们需要哪些代码中尚未明确的信息?

\n

我看到使用类型提示的 3 个正当理由:

\n
    \n
  1. 为开发者使用功能提供帮助。在迁移的情况下,forwardsbackwards函数仅由 Django 内部使用。阅读您的代码的开发人员应该了解有关迁移的知识。如果他们不知道什么appsschema_editor是什么,那么期望他们参考文档似乎是公平的,而不是为每个迁移的每个操作的每个操作和回调migrations.RunPython重新解释它。backwardsforwardsRunPython
  2. \n
  3. QA 类型检查。但类型检查仅对您自己的代码有用。您永远不会从迁移中导入函数以在代码中使用它们,因此无需检查任何内容。
  4. \n
  5. 使用内省为一些智能工具(内部或第三方)提供元信息来完成神奇的事情。该用例的一个很好的例子是 FastAPI,他们对注释的使用非常先进,并且是其 API 的强大组成部分。
  6. \n
\n

除非您的情况适合这三种情况之一,或者您有任何其他原因使用类型提示,否则不要尝试盲目地适应“策略”。不要仅仅因为可以就编写注释。保持冷静并(重新)阅读Python 之禅。:) (2)

\n

TLDR:请您的老板告诉您为什么他需要迁移的类型提示。如果答案是明确的目的,请写下提示来实现该目的。如果答案无论如何都是愚蠢的,那就写下愚蠢的类型提示。\xc2\xaf\\ (\xe3\x83\x84) /\xc2\xaf (3)

\n
\n

脚注

\n
\n

(1)双重否定可能会令人困惑。我在这里的意思是,如果有人无法解释做某事的目的,你就不需要找到不做这件事的目的。或者至少,有一个非常简单的目的:节省执行和维护所需的时间和资源。

\n
\n
\n

(2)不要试图在 Python 之禅中寻找任何特定于这种情况的原则。我的意思只是将此参考文献作为对 Python 哲学的一般提醒:保持事情简单、清晰显式的代码比糟糕的释义文档之类的东西更有价值。

\n
\n
\n

(3)如果目的是“通过 CI”之类的,我个人会推荐一些愚蠢的东西def forwards(apps: ..., schema_editor: ...) -> ...(我的意思是,用省略号对象逐字注释)。要么没有人注意到,这确实毫无意义,要么你的老板或你的同事把它扔给你,并希望有一个更明确的目的。

\n
\n

  • 很好的答案!但请永远不要建议用省略号注释某些内容,这是奇怪的 pylance 扩展,[mypy 不支持](https://mypy-play.net/?mypy=latest&python=3.10&gist=45ff54abebec4c64594c28309b1ecdf1),并且 pylance 将其视为“打字” .任何`同义词。因此请使用“typing.Any”来代替。 (3认同)

dec*_*eze 3

文档:

\n
\n

codereverse_code如果提供的话)应该是接受两个参数的可调用对象;第一个是包含与项目历史记录中的操作\xe2\x80\x99s 位置相匹配的历史模型的实例,django.apps.registry.Apps第二个是SchemaEditor.

\n

https://docs.djangoproject.com/en/stable/ref/migration-operations/#django.db.migrations.operations.RunPython

\n
\n

因此,如果您想使用类型注释数据迁移,这些是合适的注释:

\n
from django.apps.registry import Apps\nfrom django.db.backends.base.schema import BaseDatabaseSchemaEditor\n\ndef forwards(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):\n    ...\n
Run Code Online (Sandbox Code Playgroud)\n