为什么可以在 "multiple ways" 中导入 UpdateView

Why can you import UpdateView in "multiple ways"

为什么下面两种导入UpdateView的方式都有效?:

我假设 2. 是正确的方法,而 1. 行不通,但通过测试这两种方法都行得通。

你在这里看到的很常见(至少在 一些 Python 包中是这样)。如果你定义了一个 .py 文件,它就作为一个模块。例如 django.views.generic.edit 模块映射到 django/views/generic/edit.py file [GitHub].

目录也是一个 Python 模块(由于 __init__.py 文件),但默认情况下它不包含任何元素,因此这意味着 django.views.generic 会是空的。

如果我们看一下 django/views/generic/__init__.py file [GitHub],我们会看到:

from django.views.generic.base import RedirectView, TemplateView, View
# ...
from django.views.generic.edit import (
    CreateView, DeleteView, FormView, <b>UpdateView</b>,
)
# ...

__all__ = [
    'View', 'TemplateView', 'RedirectView', 'ArchiveIndexView',
    'YearArchiveView', 'MonthArchiveView', 'WeekArchiveView', 'DayArchiveView',
    'TodayArchiveView', 'DateDetailView', 'DetailView', 'FormView',
    'CreateView', <b>'UpdateView'</b>, 'DeleteView', 'ListView', 'GenericViewError',
]

# ...

因此从 generic.py 文件导入 UpdateView,并且 重新导出 class。

因此,您可以通过两种方式引用 class:通过 generic.py 文件定义的模块,或通过重新导出目录的模块,通过 __init__.py 文件.

这通常用于导出文件中定义的项目的 部分 ,以更方便的名称导出这些项目,或提供一些额外的 class es 在模块级别(例如 __init__.py 文件定义了 GenericViewError 错误)。

这个目录级模块因此"groups" 有趣的观点聚集在一起。例如 FormMixin 而不是 在此级别导出。 __init__.py 这里将(流行的)基于 class 的视图组合在一起,而通常用于定义此类通用视图的 mixins 仍然特定于文件。