Visual Studio Code 中的 Django 教程

Django 是一个高级 Python 框架,旨在快速、安全且可扩展的网页开发。Django 支持丰富的 URL 路由、页面模板和数据处理。

在这个Django教程中,你创建一个简单的Django应用,包含三个页面,使用一个通用的基础模板。你需要在Visual Studio Code的环境中创建这个应用,以便理解如何在VS Code终端、编辑器和调试器中使用Django。本教程并未涉及Django本身的各种细节,比如如何处理数据模型和创建管理界面。关于这些方面,请参阅本教程末尾的Django文档链接。

这个 Django 教程中完成的代码项目可以在 GitHub 上找到:python-sample-vscode-django-tutorial

如果你有任何问题,可以在Python扩展的讨论问答中搜索答案或提问。

前提条件

要成功完成这个Django教程,你必须完成以下步骤(与通用Python教程相同):

  1. 安装Python扩展

  2. 安装一个Python 3版本(本教程就是为此编写的)。选项包括:

    • (所有作系统)来自 python.org;通常使用页面上最先出现的 Download Python 3.9.1 按钮(或最新版本)。
    • (Linux)内置的 Python 3 安装运行良好,但要安装其他 Python 包,必须运行sudo apt install Python3-PIP在终端里。
    • (macOS)通过 macOS 上的 Homebrew 安装brew 安装 python3(macOS 上的 Python 系统安装不被支持)。
    • (所有作系统)这是从Anaconda下载的(用于数据科学目的)。
  3. 在Windows上,确保你的Python解释器的位置包含在你的PATH环境变量中。你可以通过跑步来查看该位置路径在命令提示符上。如果 Python 解释器的文件夹没有包含,打开 Windows 设置,搜索“environment”,选择为你的账户编辑环境变量,然后编辑 Path 变量加入该文件夹。

为Django教程创建一个项目环境

在本节中,你创建一个安装Django的虚拟环境。使用虚拟环境可以避免将Django安装到全局Python环境中,并且能让你精确控制应用中使用的库。虚拟环境也使创建环境的 requirements.txt 文件变得容易。

Python 环境扩展支持多种环境类型,包括 venv、conda、poetry 等。这个教程用venv,因为它内置在Python里,不需要额外工具。其他环境类型的步骤类似——详见“创建环境”。

  1. 在你的文件系统上,为这个教程创建一个项目文件夹,比如hello_django.

  2. 通过运行 VS Code 打开项目文件夹代码。或者通过运行 VS Code 并使用 File > Open Folder 命令。

  3. 使用 Python: Create Environment 命令创建虚拟环境:

    1. 打开命令面板(⇧⌘P(Windows,Linux Ctrl+Shift+P)
    2. 搜索并选择 Python:创建环境
    3. 选择 Venv 以创建 venv 环境
    4. 选择一个用于环境的Python解释器

    VS Code 创建了.venv在你的工作区里的文件夹,并自动选择新的环境。

    提示

    你也可以用Python侧边栏创建环境。展开环境管理器,选择+键进行快速创建,该按钮使用合理的默认设置。

    Django 教程:在 VS Code 中打开命令调色板

  4. 所选环境显示在VS Code状态栏右侧,('.venv': venv)指示器显示你正在使用虚拟环境:

    Django 教程:VS Code 状态栏中显示的已选环境

  5. 在虚拟环境中使用以下方法之一安装 Django:

    使用包管理界面:

    1. Python 侧边栏,展开环境管理器
    2. 右键点击你的.venv环境并选择管理包
    3. 搜索姜戈并选择安装

    使用终端:

    运行终端:从命令面板创建新终端⌃⇧'(Windows,Linux Ctrl+Shift+'),创建终端并自动激活虚拟环境。然后运行:

    python -m pip install django
    

你现在拥有了一个自成体系的环境,可以编写Django代码。VS Code 在你打开新终端时会自动激活环境。如果你在VS Code之外打开了单独的命令提示符或终端,通过运行来激活环境来源 .venv/bin/activate(Linux/macOS)或.venv\Scripts\Activate.ps1(Windows)。当命令提示符开头显示(.venv)时,你就知道环境已经激活。

创建并运行一个简约的Django应用

在Django术语中,“Django项目”由多个站点级配置文件组成,以及一个或多个“应用程序”,你部署到网络主机上以创建一个完整的网页应用。一个 Django 项目可以包含多个应用,每个应用通常在项目中都有独立的功能,同一个应用也可以存在于多个 Django 项目中。应用本身就是一个遵循Django期望的某些规范的Python包。

因此,要创建一个最小的Django应用,首先需要创建一个Django项目作为应用容器,然后再创建应用本身。在这两种情况下,你都使用Django管理工具,Django-admin安装Django包时安装了。

创建Django项目

  1. 在激活虚拟环境的VS Code终端中,执行以下命令:

    django-admin startproject web_project .
    

    就是这样STARTPROJECT命令假设(通过使用.最后)当前文件夹是你的项目文件夹,并在其中创建以下内容:

    • manage.py:该项目的Django命令行管理工具。你用以下方式来执行项目管理命令Python manage.py <命令> [选项].

    • 一个名为web_project包含以下文件:

      • __init__.py: 一个空文件,告诉 Python 这个文件夹是一个 Python 包。
      • asgi.py:为ASGI兼容的Web服务器提供服务于您的项目的入口。通常你会保持这个文件原样,因为它为生产环境的 Web 服务器提供了 hook。
      • settings.py: 包含Django项目的设置,你可以在开发Web应用的过程中进行修改。
      • urls.py: 包含Django项目的目录,开发过程中也需修改。
      • wsgi.py:为WSGI兼容的Web服务器提供服务你的项目的入口。通常你会保持这个文件原样,因为它为生产环境的 Web 服务器提供了 hook。
  2. 通过执行以下命令创建一个空的开发数据库:

    python manage.py migrate
    

    当你第一次运行服务器时,它会在文件中创建一个默认的SQLite数据库DB.sqlite3该应用旨在开发,但也可用于生产环境下的低流量网页应用。有关数据库的更多信息,请参见“数据库类型”部分。

  3. 要验证 Django 项目,确保你的虚拟环境已激活,然后用命令启动 Django 的开发服务器Python manage.py runserver.服务器运行在默认端口8000上,终端窗口中会显示如下输出:

    Watching for file changes with StatReloader
    Performing system checks...
    
    System check identified no issues (0 silenced).
    June 13, 2023 - 18:38:07
    Django version 4.2.2, using settings 'web_project.settings'
    Starting development server at http://127.0.0.1:8000/
    Quit the server with CTRL-BREAK.
    

    Django 内置的 Web 服务器用于本地开发。但当你部署到网络主机时,Django 会使用主机的 Web 服务器。该wsgi.py以及asgi.pyDjango 项目中的模块负责连接生产服务器。

    如果你想使用与默认8000不同的端口,可以在命令行中指定端口号,比如Python manage.py RunServer 5000.

  4. Ctrl+点击http://127.0.0.1:8000/在终端输出窗口打开默认浏览器的URL,地址指向该地址。如果Django安装正确且项目有效,你会看到下面显示的默认页面。VS Code 终端输出窗口还显示服务器日志。

    Django 教程:空 Django 项目的默认视图

  5. 完成后,关闭浏览器窗口,并按照终端输出窗口指示的 Ctrl+C 在 VS Code 中停止服务器。

创建一个Django应用

  1. 在VS Code终端中,激活虚拟环境,运行管理工具的StartApp命令,位于你的项目文件夹中(其中)manage.py居住地):

    python manage.py startapp hello
    

    该命令创建了一个名为你好其中包含若干代码文件和一个子文件夹。在这些项目中,你经常与之合作views.py(包含定义你网页应用中的页面的函数)以及models.py(其中包含定义你数据对象的类)。该迁徙文件夹被 Django 的管理工具用来管理数据库版本,正如本教程后面所讨论的。还有文件apps.py(应用配置),admin.py(用于创建管理接口),以及tests.py(用于创建测试),但这里不涵盖这些内容。

  2. 修改你好/views.py为了匹配以下代码,该代码为应用首页创建一个单一视图:

    from django.http import HttpResponse
    
    def home(request):
        return HttpResponse("Hello, Django!")
    
  3. 创建一个文件,你好/urls.py,内容如下。该urls.py文件是你指定模式,将不同URL路由到相应视图。下面的代码包含一条将应用根URL映射到以下""views.home你刚添加的函数你好/views.py:

    from django.urls import path
    from hello import views
    
    urlpatterns = [
        path("", views.home, name="home"),
    ]
    
  4. web_project文件夹中还包含一个urls.py文件,实际上就是处理URL路由的地方。开门web_project/urls.py并修改它以匹配以下代码(如果你愿意,可以保留教学注释)。这个代码会拉入应用的你好/urls.py使用django.urls.include,它将应用的路由包含在应用内。当一个项目包含多个应用时,这种分离非常有帮助。

    from django.contrib import admin
    from django.urls import include, path
    
    urlpatterns = [
        path("", include("hello.urls")),
        path('admin/', admin.site.urls)
    ]
    
  5. 保存所有修改过的文件。

  6. 在 VS Code 终端中,再次激活虚拟环境,运行开发服务器,Python manage.py runserver并打开浏览器http://127.0.0.1:8000/以查看一个渲染“Hello, Django”的页面。

    Django 教程:浏览器运行的基础 Django 应用

创建调试器启动配置文件

你可能已经在想有没有更简单的方法可以运行服务器并测试应用而不打字Python manage.py runserver每次都是这样。幸运的是,有的!你可以在 VS Code 中创建定制的启动配置文件,这也被用于不可避免的调试练习。

  1. 在VS Code中切换到运行视图(使用左侧活动栏或F5键)。你可能会看到“要自定义运行和调试,创建launch.json文件”的提示。这意味着你还没有launch.json包含调试配置的文件。如果你点击创建launch.json文件链接,VS Code可以帮你创建这个链接:

    Django 教程:调试面板初步视图

  2. 选择链接后,VS Code 会提示调试配置。从下拉菜单中选择Django,VS Code会生成新的launch.json文件中带有Django运行配置。该launch.json文件包含多个调试配置,每个配置都是配置阵列。

  3. 向下滚动到名为“Python: Django”的配置:

    {
      // Use IntelliSense to learn about possible attributes.
      // Hover to view descriptions of existing attributes.
      // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
      "version": "0.2.0",
      "configurations": [
        {
          "name": "Python Debugger: Django",
          "type": "debugpy",
          "request": "launch",
          "program": "${workspaceFolder}\\manage.py",
          "args": ["runserver"],
          "django": true,
          "justMyCode": true
        }
      ]
    }
    

    该配置指示 VS Code 运行“${workspaceFolder}/manage.py”使用选定的 Python 解释器和参数args清单。因此,使用这种配置启动 VS Code 调试器,就等同于运行Python manage.py runserver在VS Code终端中,与你激活的虚拟环境一起。(你可以添加端口号,比如"5000"args如果需要的话。)该“Django”:确实如此条目还指示 VS Code 启用 Django 页面模板的调试,相关内容将在本教程后面看到。

  4. 通过选择“运行>开始调试”菜单命令,或点击列表旁的绿色“开始调试”箭头(F5)来测试配置:

    Django 教程:调试工具栏上的开始调试/继续箭头

  5. Ctrl+点击http://127.0.0.1:8000/在终端输出窗口打开浏览器,查看应用是否正常运行。

  6. 完成后关闭浏览器并停止调试器。要停止调试器,可以使用停止工具栏按钮(红色方块)或运行>停止调试命令(⇧F5(Windows,Linux Shift+F5)。

  7. 你现在可以随时使用运行>开始调试来测试应用,这个功能还能自动保存所有修改过的文件。

探索调试器

调试让你有机会暂停特定代码行的运行程序。当程序暂停时,你可以检查变量,在调试控制台面板中运行代码,并利用调试中描述的功能。运行调试器还会自动保存任何修改过的文件,在调试会话开始前。

开始前:确保你在最后一节结束时通过终端中的Ctrl+C停止运行应用。如果你让应用在一个终端上运行,它仍然拥有该端口。因此,当你用同一个端口在调试器中运行应用时,原始运行的应用会处理所有请求,你不会看到正在调试的应用有任何活动,程序也不会在断点停止。换句话说,如果调试器似乎不起作用,确保没有其他应用实例仍在运行。

  1. 你好/urls.py,向URL 模式列表:

    path("hello/<name>", views.hello_there, name="hello_there"),
    

    第一个论证路径定义一条路由“hello/”,接受名为name的变量字符串。字符串传递给views.hello_there第二个参数指定为路径.

    URL 路由是区分大小写的。例如,路线/你好/<名字>与 不同于/你好,<名字>.如果你想用同一个视图函数处理两者,就为每个变体定义路径。

  2. 替换 的内容views.py并用以下代码定义hello_there你可以在调试器中逐步完成:

    import re
    from django.utils.timezone import datetime
    from django.http import HttpResponse
    
    def home(request):
        return HttpResponse("Hello, Django!")
    
    def hello_there(request, name):
        now = datetime.now()
        formatted_now = now.strftime("%A, %d %B, %Y at %X")
    
        # Filter the name argument to letters only using regular expressions. URL arguments
        # can contain arbitrary text, so we restrict to safe characters only.
        match_object = re.match("[a-zA-Z]+", name)
    
        if match_object:
            clean_name = match_object.group(0)
        else:
            clean_name = "Friend"
    
        content = "Hello there, " + clean_name + "! It's " + formatted_now
        return HttpResponse(content)
    

    名称URL路由中定义的变量作为参数给出hello_there功能。如代码注释所述,务必过滤任意用户提供的信息,以避免对应用的各种攻击。在这种情况下,代码会将名称参数过滤为仅包含字母,从而避免了控制字符、HTML 等的注入。(当你在下一节使用模板时,Django 会自动过滤,你不需要这些代码。)

  3. 在代码的第一行设置断点hello_there函数(现在 = DateTime。now())通过以下任一作:

    • 当光标停留在该行时,按F9,或者,
    • 当光标停留在该行时,选择“运行>切换断点菜单”命令,或者,
    • 直接点击行号左侧的边缘(悬停时会出现一个渐变的红点)。

    断点以红点形式出现在左边缘:

    Django 教程:hello_there函数首行的断点集合

  4. 通过选择“运行>开始调试”菜单命令,或点击列表中的绿色“开始调试”箭头(F5)来启动调试器:

    Django 教程:调试工具栏上的开始调试/继续箭头

    注意状态栏颜色变化以表示正在调试:

    Django 教程:调试状态栏的出现

    VS Code 中还会出现一个调试工具栏(如下图),命令顺序如下:暂停(或继续,F5)、Step Over(F10)、Step In(F11)、Step Out(Windows,Linux Shift+F11)、Restart(⇧⌘F5(Windows,Linux Ctrl+Shift+F5)和停止(⇧F5,Windows,Linux Shift+F5)。关于每个命令的描述,请参见 VS Code 调试

    Django 教程:VS Code 调试工具栏

  5. 输出显示在“Python 调试控制台”终端中。打开浏览器并导航到http://127.0.0.1:8000/hello/VSCode. 在页面渲染之前,VS Code 会在你设置的断点处暂停程序。断点上的小黄箭头表示这是下一行要运行的代码。

    Django 教程:VS Code 在断点处暂停

  6. 使用 Step Over 来运行现在 = DateTime。now()陈述。

  7. 在 VS Code 窗口的左侧,你会看到一个变量面板,显示本地变量,例如现在,以及诸如名称. 下面是观察调用栈断点的窗格(详见 VS Code 调试)。在本地部分,尝试展开不同的值。你也可以双击(或使用回车键(Windows,Linux F2)来修改它们。更改变量,如现在然而,可能会破坏程序。开发者通常只在代码本身没有产生正确值时才进行修改。

    Django 教程:调试时 VS Code 中的局部变量和参数

  8. 当程序暂停时,调试控制台面板(与终端面板中的“Python 调试控制台”不同)允许你尝试表达式,并利用当前程序状态尝试代码片段。例如,一旦你跨越了代码线现在 = DateTime。now()你可以尝试不同的日期/时间格式。在编辑器中,选择以下代码now.strftime(“%A, %d %B, %Y at %X”)然后右键点击并选择“调试:评估”,将代码发送到调试控制台,运行如下:

    now.strftime("%A, %d %B, %Y at %X")
    'Friday, 07 September, 2018 at 07:46:32'
    

    提示调试控制台还会显示应用内部可能不会出现的异常。例如,如果您在运行和调试视图的调用栈区域看到“异常暂停”消息,切换到调试控制台查看异常消息。

  9. 把这行复制到调试控制台底部的>提示词里,试着更改格式:

    now.strftime("%A, %d %B, %Y at %X")
    'Tuesday, 13 June, 2023 at 18:03:19'
    now.strftime("%a, %d %b, %Y at %X")
    'Tue, 13 Jun, 2023 at 18:03:19'
    now.strftime("%a, %d %b, %y at %X")
    'Tue, 13 Jun, 23 at 18:03:19'
    
  10. 如果你愿意,可以再多看几行代码,然后选择继续(F5)让程序运行。浏览器窗口显示结果:

    Django 教程:修改程序的结果

  11. 例如,将代码中的行更改为不同的datetime格式Now.strftime(“%a, %d %b, %y at %X”),然后保存文件。Django 服务器会自动重新加载,这意味着更改将被应用而无需重启调试器。在浏览器中刷新页面以查看更新情况。

  12. 完成后关闭浏览器并停止调试器。要停止调试器,可以使用停止工具栏按钮(红色方块)或运行>停止调试命令(⇧F5(Windows,Linux Shift+F5)。

提示:为了方便反复访问某个特定网址,比如http://127.0.0.1:8000/hello/VSCode,使用印刷在文件中的某个语句,比如views.py. URL会出现在VS Code终端,你可以用Ctrl+点击在浏览器中打开。

前往定义并查看定义命令

在使用 Django 或其他库时,你可能想检查这些库中的代码。VS Code 提供了两个方便的命令,可以直接导航到任何代码中类和其他对象的定义:

  • Go to Definition 从你的代码跳转到定义对象的代码。例如,在views.py,右键点击HttpResponse首页函数并选择“进入定义”(或使用F12),这样可以导航到Django库中的类定义。

  • 窥视定义⌥F12(Windows Alt+F12,Linux Ctrl+Shift+F10),同样在右键右键菜单中),类似,但直接在编辑器中显示类定义(在编辑器窗口留出空间以避免代码模糊)。按 Esc 关闭窥视窗口,或使用右上角的 x

    Django 教程:内联显示 Flask 类的 Peek 定义

用模板渲染页面

你在教程中创建的应用只用Python代码生成纯文本网页。虽然可以直接在代码中生成 HTML,但开发者避免这样做,因为这会让应用面临跨站脚本攻击(XSS)。hello_there例如,这个教程的功能,有人可能会想到用类似的代码格式化输出内容 = “<h1>你好,” + clean_name + “!</h1>”,其中结果为内容直接提供给浏览器。这种开口允许攻击者在最终clean_name因此最终会在浏览器中运行。

更好的做法是完全不包含HTML代码,使用模板,让代码只关注数据值,而不涉及渲染。

在Django中,模板是一个HTML文件,包含代码在运行时提供的值占位符。Django 模板引擎负责渲染页面时的替换,并提供自动转义以防止 XSS 攻击(也就是说,如果你尝试在数据值中使用 HTML,你会看到的 HTML 只显示为纯文本)。因此,代码只关注数据值,模板则只关注标记。Django 模板提供了灵活的选项,比如模板继承,允许你定义带有常见标记的基础页面,然后基于该基础添加页面特定内容。

在本节中,你首先使用模板创建一个单页。在后续章节中,你配置应用提供静态文件,然后创建多个页面,每个页面包含来自基础模板的导航栏。Django 模板还支持控制流和迭代,正如你在本教程后面在模板调试的背景下看到的。

  1. web_project/settings.py文件,定位INSTALLED_APPS列出并添加以下条目,确保项目知道该应用,以便能够处理模板:

    'hello',
    
  2. 你好文件夹,创建一个名为模板,然后是另一个名为你好以匹配应用名称(这种两层文件夹结构是典型的 Django 惯例)。

  3. 模板/Hello文件夹,创建一个名为的文件hello_there.html内容如下。该模板包含两个名为“name”和“date”的数据值占位符,分别由一对大括号和所有其他不变文本都是模板的一部分,格式标记(例如{{}}<强壮>).如你所见,模板占位符还可以包括格式化,比如管道后面的表达式|符号,在此例中使用了Django内置的日期滤波器和时间滤波器。代码只需传递datetime,而无需传递预格式字符串:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title>Hello, Django</title>
        </head>
        <body>
            <strong>Hello there, {{ name }}!</strong> It's {{ date | date:"l, d F, Y" }} at {{ date | time:"H:i:s" }}
        </body>
    </html>
    
  4. views.py,添加以下导入语句:

    from django.shortcuts import render
    
  5. 还有views.py,修改hello_there用于函数django.shortcuts.render加载模板并提供模板上下文的方法。上下文是模板中使用的变量集合。该渲染函数 会接收请求对象,然后是模板路径相对于模板文件夹,然后是上下文对象。(开发者通常会给模板命名和使用它们的函数一样,但不需要匹配的名称,因为代码中总是引用准确的文件名。)

    def hello_there(request, name):
        print(request.build_absolute_uri()) #optional
        return render(
            request,
            'hello/hello_there.html',
            {
                'name': name,
                'date': datetime.now()
            }
        )
    

    你可以看到代码现在更简单,只关注数据值,因为标记和格式都包含在模板中。

  6. 启动程序(在调试器内部或外部,使用⌃F5(Windows,Linux Ctrl+F5),导航到/hello/name URL,观察结果。

  7. 另外,试着用类似这样的名字导航到 /hello/name URL<a%20value%20that%20cold%20be%20HTML>看到Django在工作时自动逃脱。“name”值在浏览器中以纯文本形式显示,而不是实际渲染的元素。

提供静态文件

静态文件是你的网页应用针对某些请求(如CSS文件)返回的内容片段。提供静态文件需要INSTALLED_APPS列表settings.py包含django.contrib.staticfiles,该系统默认包含。

在Django中提供静态文件是一种艺术,尤其是在部署到生产环境时。这里展示的是一种简单方法,既适用于Django开发服务器,也适用于像Gunicorn这样的生产服务器。然而,静态文件的完整讨论超出本教程范围,更多信息请参见Django文档中的“管理静态文件”。

切换到生产环境时,请导航至settings.py, setDEBUG=False,并且变ALLOWED_HOSTS = ['*']允许特定的主机。使用容器时可能会增加额外的工作量。详情请参见第13期

准备好应用中的静态文件

  1. 在项目中web_project/urls.py,添加以下内容进口陈述:

    from django.contrib.staticfiles.urls import staticfiles_urlpatterns
    
  2. 在同一文件中,在结尾添加以下一行,包含项目识别的标准静态文件 URL:

    urlpatterns += staticfiles_urlpatterns()
    

在模板中引用静态文件

  1. 你好文件夹,创建一个名为静态.

  2. 静态文件夹,创建一个名为你好,与应用名称相符。

    这个额外子文件夹的原因是,当你将Django项目部署到生产服务器时,你会把所有静态文件收集到一个文件夹里,然后由专门的静态文件服务器提供。该静电/喂子文件夹确保当应用的静态文件被收集时,它们会放在应用专用子文件夹中,不会与同一项目中其他应用的文件发生冲突。

  3. 静电/喂文件夹,创建一个名为的文件site.css内容如下。输入代码后,还要注意VS Code为CSS文件提供的语法高亮,包括彩色预览。

    .message {
        font-weight: 600;
        color: blue;
    }
    
  4. templates/hello/hello_there.html,在<标题>元素。该{% 负载静止 %}标签是一个自定义的Django模板标签集,允许你使用{% 静态 %}用来指代像样式表这样的文件。

    {% load static %}
    <link rel="stylesheet" type="text/css" href="{% static 'hello/site.css' %}" />
    
  5. 还有templates/hello/hello_there.html替换内容<身体>元素具有以下标记,使用了信息风格代替<强壮>标签:

    <span class="message">Hello, there {{ name }}!</span> It's {{ date | date:'l, d F, Y' }} at {{ date | time:'H:i:s' }}.
    
  6. 运行应用,导航到/hello/name的URL,观察消息显示为蓝色。完成后关闭应用。

使用 collectstatic 命令

对于生产部署,通常你会把应用中的所有静态文件收集到一个文件夹里,使用Python manage.py collectstatic指挥部。然后你可以使用专用的静态文件服务器来提供这些文件,这通常能带来更好的整体性能。以下步骤展示了该集合的制作过程,尽管在Django开发服务器运行时不会使用该集合。

  1. web_project/settings.py,添加以下一行,定义静态文件收集的位置,当你使用collectstatic指挥:

    STATIC_ROOT = BASE_DIR / 'static_collected'
    
  2. 在终端里,执行以下命令Python manage.py collectstatic并观察你好/site.css被复制到顶层static_collected文件夹旁边manage.py.

  3. 实际上,跑collectstatic只要你更改静态文件,并且在部署到生产环境之前,

创建多个模板来扩展基础模板

由于大多数网页应用有多页,且这些页面通常共享许多共同元素,开发者将这些共同元素拆分为基础页面模板,其他页面模板再进行扩展。(这也称为模板继承,意味着扩展页面继承了基础页面的元素。)

另外,因为你很可能会创建多个扩展同一个模板的页面,所以在 VS Code 里创建一个代码片段,这样你就能快速初始化新的页面模板。片段帮助你避免繁琐且易出错的复制粘贴作。

以下章节将介绍这一过程的不同环节。

创建基础页面模板和样式

Django 中的基础页面模板包含了一组页面的所有共享部分,包括对 CSS 文件、脚本文件等的引用。基础模板还定义一个或多个块标签,内容扩展模板期望覆盖这些内容。块标签的定义为{% 街区<姓名> %}以及{% 端块 %}无论是基础模板还是扩展模板。

以下步骤演示创建基础模板。

  1. 模板/Hello文件夹,创建一个名为的文件layout.html以下内容包含名为“title”和“content”的块。如你所见,标记定义了一个简单的导航栏结构,链接到主页、关于和联系方式页面,这些页面可在后面的部分创建。注意Django的使用{% URL %}标签通过对应的URL模式名称来指代其他页面,而不是通过相对路径。

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8"/>
        <title>{% block title %}{% endblock %}</title>
        {% load static %}
        <link rel="stylesheet" type="text/css" href="{% static 'hello/site.css' %}"/>
    </head>
    
    <body>
    <div class="navbar">
        <a href="{% url 'home' %}" class="navbar-brand">Home</a>
        <a href="{% url 'about' %}" class="navbar-item">About</a>
        <a href="{% url 'contact' %}" class="navbar-item">Contact</a>
    </div>
    
    <div class="body-content">
        {% block content %}
        {% endblock %}
        <hr/>
        <footer>
            <p>&copy; 2018</p>
        </footer>
    </div>
    </body>
    </html>
    
  2. 将以下样式添加到杂音/喂/site.css在现有“消息”样式下方,并保存文件。(本攻略不试图展示响应式设计;这些样式仅能产生一个相当有趣的结果。)

    .navbar {
        background-color: lightslategray;
        font-size: 1em;
        font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
        color: white;
        padding: 8px 5px 8px 5px;
    }
    
    .navbar a {
        text-decoration: none;
        color: inherit;
    }
    
    .navbar-brand {
        font-size: 1.2em;
        font-weight: 600;
    }
    
    .navbar-item {
        font-variant: small-caps;
        margin-left: 30px;
    }
    
    .body-content {
        padding: 5px;
        font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }
    

此时你可以运行应用,但因为你没有在任何地方使用基础模板,也没有更改任何代码文件,结果和上一步一样。完成剩余部分以查看最终效果。

创建代码片段

因为你在下一节创建的三页会延伸layout.html它节省了创建代码片段以初始化一个带有相应参考基础模板的新模板文件的时间。代码片段提供了来自单一来源的一致代码,避免了从现有代码复制粘贴时可能出现的错误。

  1. 在 VS Code 中,选择文件(Windows/Linux)或代码(macOS),菜单,然后选择偏好设置>用户片段

  2. 在出现的列表中,选择 html。(如果你之前创建过摘要,选项可能会在列表中的“现有片段”部分显示为“html.json”。)

  3. VS代码打开后html.json,将下面的代码添加到现有的卷括号内。(此处未显示的解释性注释描述了诸如0美元行指示 VS Code 插入片段后光标的位置):

    "Django Tutorial: template extending layout.html": {
        "prefix": "djextlayout",
        "body": [
            "{% extends \"hello/layout.html\" %}",
            "{% block title %}",
            "$0",
            "{% endblock %}",
            "{% block content %}",
            "{% endblock %}"
        ],
    
        "description": "Boilerplate template that extends layout.html"
    },
    
  4. 拯救html.json文件(⌘S(Windows,Linux Ctrl+S)。

  5. 现在,每当你开始输入该摘要的前缀时,比如DJEXTVS Code 提供了该摘要作为自动补全选项,如下节所示。你也可以使用“插入摘要”命令从菜单中选择摘要。

关于代码片段的更多信息,请参见“创建代码片段”。

使用代码片段添加页面

有了代码片段后,你可以快速创建首页、关于页面和联系方式的模板。

  1. 模板/Hello文件夹,创建一个名为home.html, 然后开始输入DJEXT要查看该摘要以完备形式出现:

    Django 教程:djextlayout 代码片段的自动补全

    当你选择完成时,片段的代码会与光标一起出现在片段插入点上:

    Django 教程:插入 djextlayout 代码片段

  2. 在“标题”块插入点,写道首页,在“内容”块中,写成<p>Visual Studio Code Django 教程主页。</p>然后保存文件。这些行是扩展页面模板中唯一独特的部分:

  3. 模板/Hello文件夹,创建about.html,使用该摘要插入样板标记,插入关于我们以及<p>关于Visual Studio Code Django教程的页面。</p>分别在“标题”和“内容”块中保存文件。

  4. 重复前一步来创建templates/hello/contact.html使用联系我们以及<p>Contact 关于 Visual Studio Code Django 教程的页面。</p>.

  5. 在应用里urls.py为/about和/contact页面添加路线。请注意名称路径函数定义了你在{% URL %}模板里的标签。

    path("about/", views.about, name="about"),
    path("contact/", views.contact, name="contact"),
    
  6. views.py添加指向各自页面模板的/about和/contact路由函数。还要修改首页函数home.html模板。

    # Replace the existing home function with the one below
    def home(request):
        return render(request, "hello/home.html")
    
    def about(request):
        return render(request, "hello/about.html")
    
    def contact(request):
        return render(request, "hello/contact.html")
    

运行应用

所有页面模板都准备好后,保存views.py运行应用,打开浏览器查看首页。在页面间导航,确认页面模板是否正确扩展了基础模板。

Django 教程:应用从基础模板中渲染一个通用导航栏

处理数据、数据模型和迁移

许多Web应用都处理数据库中存储的信息,Django使得用模型来表示数据库中的对象变得简单。在Django中,模型是Python类,源自django.db.models.model,表示特定的数据库对象,通常是表。你把这些课程放进一个应用里models.py档案。

用Django,你几乎完全通过代码定义的模型来处理数据库。Django的“迁移”会自动处理底层数据库的所有细节,随着模型的演进。一般工作流程如下:

  1. 对你的模型进行修改models.py档案。
  2. 执行Python manage.py makemigrations生成脚本迁徙这些文件夹将数据库从当前状态迁移到新状态。
  3. 执行Python manage.py 迁移将脚本应用到实际数据库中。

迁移脚本实际上记录了你随时间对数据模型所做的所有增量变更。通过应用迁移,Django 会更新数据库以匹配你的模型。由于每个增量更改都有自己的脚本,Django 可以自动将数据库的旧版本(包括新数据库)迁移到当前版本。因此,你只需关注你的模型models.py从未与底层数据库模式或迁移脚本相关联。你让Django来做那部分!

在代码中,你也只用模型类来存储和检索数据;Django负责底层细节。唯一的例外是你可以用 Django 管理工具 loaddata 命令写入数据库。该工具通常用于在迁移指令已初始化了模式。

当使用DB.sqlite3文件,你也可以直接使用像SQLite浏览器这样的工具来作数据库。使用这种工具添加或删除表中的记录是可以的,但避免更改数据库模式,因为那样数据库会与你的应用模型不同步。相反,换模型,跑迁移然后跑迁移.

数据库类型

默认情况下,Django 包含DB.sqlite3提交适合开发工作的应用数据库。正如《When to use SQLite》(sqlite.org)中所述,SQLite对于流量少于10万的中低流量网站表现良好,但不推荐用于大量访问量。它也仅限于单台计算机,因此无法用于任何多服务器场景,如负载均衡和地理复制。

基于这些原因,建议使用生产级数据存储,如PostgreSQLMySQLSQL Server。有关 Django 对其他数据库的支持信息,请参见数据库设置。你也可以用 Python 的 Azure SDK 来处理 Azure 存储服务,比如表和 blob。

定义模型

Django 模型同样是从 Python 衍生而来的类django.db.model.Models,你将它放入应用的models.py档案。在数据库中,每个模型会自动获得一个独特的 ID 字段,名为身份证.所有其他字段都用以下类型定义为类的属性django.db.models例如:查尔菲尔德(有限文本),文本字段(无限文本),电子邮件字段,URLField,整数场,十进制字段,布利恩菲尔德.日期时间场,ForeignKey, 和,以及其他。(详情请参见Django文档中的模型字段参考。)

每个字段都具有一些属性,比如max_length.该空白=真属性表示该字段是可选的;空=真意味着某个值是可选的。还有一个选择该属性限制值只能在数据值/显示值元组数组中取值。

例如,将以下类加入models.py定义一个表示简单消息日志中已过日期条目的数据模型:

from django.db import models
from django.utils import timezone

class LogMessage(models.Model):
    message = models.CharField(max_length=300)
    log_date = models.DateTimeField("date logged")

    def __str__(self):
        """Returns a string representation of a message."""
        date = timezone.localtime(self.log_date)
        return f"'{self.message}' logged on {date.strftime('%A, %d %B, %Y at %X')}"

模型类可以包含返回从其他类属性计算出的值的方法。模型通常包括__str__返回实例字符串表示的方法。

迁移数据库

因为你通过编辑改变了数据模型models.py你需要更新数据库本身。在 VS Code 中,打开一个激活虚拟环境的终端(使用终端:创建新终端命令,⌃⇧'(Windows,Linux Ctrl+Shift+'),进入项目文件夹,执行以下命令:

python manage.py makemigrations
python manage.py migrate

看看迁徙文件夹以查看迁移生成。你也可以查看数据库本身,看看模式是否更新了。

如果你在执行命令时看到错误,确保你没有用之前步骤遗留的调试终端,因为它们可能没有激活虚拟环境。

通过模型使用数据库

模型已到位且数据库迁移完成后,你可以仅用模型存储和检索数据。在这个部分,你会为应用添加一个表单页面,通过它来记录消息。然后你修改主页以显示这些信息。因为你在这里修改了很多代码文件,所以要注意细节。

  1. 你好文件夹(你有views.py),创建一个名为forms.py以下代码定义了一个包含从数据模型中提取字段的Django形式,日志消息:

    from django import forms
    from hello.models import LogMessage
    
    class LogMessageForm(forms.ModelForm):
        class Meta:
            model = LogMessage
            fields = ("message",)   # NOTE: the trailing comma is required
    
  2. 模板/Hello文件夹,创建一个名为log_message.html其中内容如下,假设模板有一个变量 名为形式以定义形态的主体。然后它会添加一个带有“日志”标签的提交按钮。

    {% extends "hello/layout.html" %}
    {% block title %}
        Log a message
    {% endblock %}
    {% block content %}
        <form method="POST" class="log-form">
            {% csrf_token %}
            {{ form.as_p }}
            <button type="submit" class="save btn btn-default">Log</button>
        </form>
    {% endblock %}
    

    :Django的{% csrf_token %}TAG提供防止跨站请求伪造的保护。详情请参见Django文档中的跨站请求伪造保护

  3. 在应用里杂音/喂/site.css文件,添加一条规则使输入表单更宽:

    input[name=message] {
        width: 80%;
    }
    
  4. 在应用里urls.py文件,添加新页面的路线:

    path("log/", views.log_message, name="log"),
    
  5. views.py,定义名为的视图log_message(如URL路由所指)。该视图处理HTTP GET和POST两种情况。在GET情形中(其他:它只是显示你在前面步骤中定义的表单。在POST情况下,它从表单中检索数据到数据对象(信息),设置时间戳,然后保存该对象,此时该对象被写入数据库:

    # Add these to existing imports at the top of the file:
    from django.shortcuts import redirect
    from hello.forms import LogMessageForm
    from hello.models import LogMessage
    
    # Add this code elsewhere in the file:
    def log_message(request):
        form = LogMessageForm(request.POST or None)
    
        if request.method == "POST":
            if form.is_valid():
                message = form.save(commit=False)
                message.log_date = datetime.now()
                message.save()
                return redirect("home")
        else:
            return render(request, "hello/log_message.html", {"form": form})
    
  6. 在你准备好尝试所有东西之前,还有一步!在templates/hello/layout.html在“navbar” div中添加消息日志页面的链接:

    <!-- Insert below the link to Home -->
    <a href="{% url 'log' %}" class="navbar-item">Log Message</a>
    
  7. 运行应用,打开浏览器进入主页。在导航栏选择日志消息链接,该链接应显示消息记录页面:

    Django 教程:添加到应用中的消息记录页面

  8. 输入消息,选择日志,你应该会被带回首页。主页还没有显示任何已记录的消息(你马上会解决这个问题)。也欢迎你再多留几条消息。如果你愿意,可以用像SQLite Browser这样的工具查看数据库,看看记录是否已经创建。请将数据库设置为只读,或者记得在使用应用前关闭数据库,否则应用会失败,因为数据库被锁定。

  9. 完成后关闭应用。

  10. 现在修改主页以显示已记录的消息。首先更换应用内容templates/hello/home.html请归档下方标记。该模板期望有一个名为message_list.如果收到(已通过{% 如果message_list %}然后它会对该列表进行迭代(该列表){message_list %中留言}标签)用于为每条消息生成表行。否则页面显示尚未记录任何消息。

    {% extends "hello/layout.html" %}
    {% block title %}
        Home
    {% endblock %}
    {% block content %}
        <h2>Logged messages</h2>
    
        {% if message_list %}
            <table class="message_list">
                <thead>
                <tr>
                    <th>Date</th>
                    <th>Time</th>
                    <th>Message</th>
                </tr>
                </thead>
                <tbody>
                {% for message in message_list %}
                    <tr>
                        <td>{{ message.log_date | date:'d M Y' }}</td>
                        <td>{{ message.log_date | time:'H:i:s' }}</td>
                        <td>
                            {{ message.message }}
                        </td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        {% else %}
            <p>No messages have been logged. Use the <a href="{% url 'log' %}">Log Message form</a>.</p>
        {% endif %}
    {% endblock %}
    
  11. 杂音/喂/site.css,添加一条规则来稍微调整表格格式:

    .message_list th,td {
        text-align: left;
        padding-right: 15px;
    }
    
  12. views.py,导入Django的通用版列表视图我们用它来实现主页:

    from django.views.generic import ListView
    
  13. 还有views.py,替换首页函数,类首页列表视图,源自列表视图,与日志消息建模并实现一个函数get_context_data生成模板的上下文。

    # Remove the old home function if you want; it's no longer used
    
    class HomeListView(ListView):
        """Renders the home page, with a list of all messages."""
        model = LogMessage
    
        def get_context_data(self, **kwargs):
            context = super(HomeListView, self).get_context_data(**kwargs)
            return context
    
  14. 在应用里urls.py,导入数据模型:

    from hello.models import LogMessage
    
  15. 还有urls.py为新视图创建一个变量,检索最近的五个日志消息对象按降序排列(即查询数据库),然后在模板上下文中为数据提供名称(message_list),并识别用于使用的模板:

    home_list_view = views.HomeListView.as_view(
        queryset=LogMessage.objects.order_by("-log_date")[:5],  # :5 limits the results to the five most recent
        context_object_name="message_list",
        template_name="hello/home.html",
    )
    
  16. urls.py, 修改通往主页的路径以使用home_list_view变量:

        # Replace the existing path for ""
        path("", home_list_view, name="home"),
    
  17. 启动应用,打开浏览器进入主页,现在应该会显示以下消息:

    Django 教程:应用主页显示数据库中的消息

  18. 完成后关闭应用。

使用带有页面模板的调试器

如前一节所示,页面模板可以包含以下程序指令{message_list %中留言}以及{% 如果message_list %}而不仅仅是被动的陈述元素,如{% URL %}以及{% 阻挡 %}. 因此,模板中可能出现编程错误,就像其他程序代码一样。

幸运的是,VS Code 的 Python 扩展提供了模板调试功能,前提是你有“Django”:确实如此在调试配置中(正如你已经做的那样)。以下步骤展示了这一能力:

  1. templates/hello/home.html,在两个{% 如果message_list %}以及{message_list %中留言}线条,如下图黄色箭头所示:

    Django 教程:在 Django 页面模板中设置断点

  2. 在调试器中运行应用,打开浏览器进入主页。(如果你已经在运行调试器,设置断点后无需重启应用;只需刷新页面即可。)注意 VS Code 会在模板中入侵调试器{% 如果 %}语句,显示变量面板中的所有上下文变量:

    Django 教程:调试器在页面模板的断点处停止

  3. 使用Step Over(F10)命令逐步浏览模板代码。注意调试器会对所有声明语句进行步进,并在任何过程代码处暂停。例如,逐步通过{message_list %中留言}循环可以让你检查 中的每个值信息并且可以让你踩到像这样的线条<td>{{ message.log_date | date:'d M Y'}}</td>.

  4. 你也可以在调试控制台面板里处理变量。(Django 会过滤日期但目前在主机上并未提供。)

  5. 准备好后,选择继续(F5)以完成应用运行,并在浏览器中查看渲染后的页面。完成后停止调试器。

可选活动

以下章节介绍了你在使用 Python 和 Visual Studio Code 时可能发现有用的额外步骤。

为环境创建一个requirements.txt文件

当你通过源码控制或其他方式分享应用代码时,复制所有文件到虚拟环境中并不合理,因为接收方总能自己重建那个环境。

因此,开发者通常会省略源代码控制中的虚拟环境文件夹,而是用requirements.txt档案。

虽然你可以手动创建文件,但你也可以使用PIP冻结命令以生成文件,基于激活环境中安装的具体库:

  1. 通过 Python 的 Select Interpreter 命令选择了你所选环境,然后运行 Terminal: Create New Terminal 命令(⌃⇧'(Windows,Linux Ctrl+Shift+'))),打开激活该环境的终端。

  2. 在终端里,跑PIP冻结> requirements.txt以创建requirements.txt文件放在你的项目文件夹里。

任何收到项目副本的人(或任何构建服务器)只需运行PIP install -r requirements.txt命令中用于重新安装应用在活跃环境中依赖的包。

PIP冻结列出你当前环境中安装的所有 Python 包,包括你目前没有使用的包。命令还列出了带有精确版本号的包,你可能想把它们转换成范围,以便未来更有灵活性。欲了解更多信息,请参见 pip 命令文档中的需求文件

创建一个超级用户并启用管理界面

默认情况下,Django 为一个受认证保护的网页应用提供管理界面。该接口通过内置的django.contrib.admin该应用默认包含在项目中INSTALLED_APPS列表(settings.py),认证则由内置的django.contrib.auth应用,也在INSTALLED_APPS默认。

请执行以下步骤以启用管理接口:

  1. 在应用里创建超级用户账户,方法是在 VS Code 中打开终端,然后执行该命令Python manage.py CreateSuperUser --username=<username> --email=<email>,替换<用户名>以及<邮件>当然,是你的个人信息。当你执行命令时,Django 会提示你输入并确认密码。

    记得记住你的用户名和密码组合。这些是你用来验证应用的凭证。

  2. 在项目层面添加以下 URL 路由urls.py (web_project/urls.py在本教程中),以指向内置的管理界面:

    # This path is included by default when creating the app
     path("admin/", admin.site.urls),
    
  3. 运行服务器,然后打开浏览器进入应用的 /admin 页面(例如http://127.0.0.1:8000/admin当使用开发服务器时)。

  4. 登录页面出现了,感谢django.contrib.auth.输入你的超级用户凭证。

    Django 教程:默认 Django 登录提示

  5. 认证后,你会看到默认的管理页面,通过它管理用户和组:

    Django 教程:默认的 Django 管理界面

你可以根据喜好自定义管理界面。例如,你可以提供编辑和删除数据库条目的功能。关于自定义的更多信息,请参阅 Django 管理网站的文档

使用 Container Tools 扩展为 Django 应用创建一个容器

容器工具扩展使得从Visual Studio Code轻松构建、管理和部署容器化应用变得简单。如果你有兴趣学习如何为本教程中开发的Django应用创建Python容器,可以看看Python in a container教程,它会带你一步步:

  • 创建一个Dockerfile描述一个简单的Python容器的文件。
  • 构建、运行并验证Django应用的功能。
  • 调试运行在容器中的应用。

下一步

恭喜你完成了这次在Visual Studio Code中使用Django的作攻略!

本教程完成的代码项目可在GitHub上找到:python-sample-vscode-django-tutorial

在这篇教程中,我们只触及了Django能做的一切。请务必访问Django文档官方Django教程,了解更多关于视图、模板、数据模型、URL路由、管理界面、其他类型数据库使用、部署到生产环境等方面的更多细节。

想在生产网站上试用你的应用,可以看看教程《使用Docker Container将Python应用部署到Azure App Service》。Azure 还提供了一个标准容器,即 Linux 上的 App Service,你可以在 VS Code 内部署 Web 应用。

你也可以参考VS Code文档中与Python相关的以下文章: