Visual Studio Code中使用Django
Django是旨在快速,安全和可扩展的Web开发的高级Python框架。Django包括对URL路由,页面模板和数据处理的丰富支持。
在本Django教程中,您将创建一个简单的Django应用,该应用包含三个使用通用基本模板的页面。您可以在Visual Studio Code的上下文中创建此应用程序,以了解如何在VS Code终端,编辑器和调试器中使用Django。本教程不会探讨有关Django本身的各种细节,例如使用数据模型和创建管理界面。
该Django教程中完整的代码项目可在GitHub上找到:python-sample-vscode-django-tutorial。
先决条件#
要成功完成本Django教程,您必须执行以下操作(与一般Python教程中的步骤相同):
-
安装Python扩展。
-
安装Python 3版本(编写本教程)。选项包括:
- (所有操作系统)从python.org下载;通常使用页面上首先显示的Download Python 3.7.0按钮(或最新版本)。
- (Linux)内置的Python 3安装效果很好,但是要安装其他Python软件包,您必须
sudo apt install python3-pip
在终端中运行。 - (macOS)使用在MacOS上通过Homebrew进行的安装
brew install python3
(不支持在macOS上进行Python的系统安装)。 - (所有操作系统)从Anaconda下载(出于数据科学目的)。
-
在Windows上,确保PATH环境变量中包含Python解释器的位置。您可以通过
path
在命令提示符处运行来检查位置。如果不包括Python解释器的文件夹,请打开Windows设置,搜索“环境”,选择“为您的帐户编辑环境变量”,然后编辑“路径”变量以包含该文件夹。
创建Django的教程项目环境#
在本部分中,您将创建一个安装了Django的虚拟环境。使用虚拟环境可以避免将Django安装到全局Python环境中,并可以精确控制应用程序中使用的库。虚拟环境还使创建环境的requirements.txt文件变得容易。
-
在文件系统上,为本教程创建一个项目文件夹,例如
hello_django
。 -
在该文件夹中,使用以下命令(适用于您的计算机)创建一个
env
基于当前解释器命名的虚拟环境:<span style="color:#333333"><code><span style="color:#008000"># macOS/Linux</span> <span style="color:#000000">sudo apt-get install python3-venv </span><span style="color:#008000"># If needed</span> <span style="color:#000000">python3 -m venv env</span> <span style="color:#008000"># Windows</span> <span style="color:#000000">python -m venv env</span></code></span>
注意:运行上述命令时,请使用标准Python安装。如果
python.exe
从Anaconda安装中使用,则会看到错误,因为surepip模块不可用,并且环境处于未完成状态。 -
通过运行
code .
或通过运行VS Code并使用“文件” >“打开文件夹”命令来在VS Code中打开项目文件夹。 -
在VS Code中,打开命令面板(“视图” >“命令面板”或(Ctrl + Shift + P))。然后选择Python:Select Interpreter命令:
-
该命令列出了VS Code可以自动定位的可用解释器的列表(您的列表会有所不同;如果看不到所需的解释器,请参阅配置Python环境)。从列表中,选择项目文件夹中以
./env
或开头的虚拟环境.\env
: -
运行终端:从命令面板创建新的集成终端(Ctrl + Shift +`),该命令面板将创建一个终端并通过运行其激活脚本自动激活虚拟环境。
注意:在Windows上,如果您的默认终端类型是PowerShell,则可能会看到一个错误,表明它无法运行activate.ps1,因为系统上已禁用了运行脚本。该错误提供了有关如何允许脚本的信息链接。否则,请使用终端:选择“默认Shell ”将“命令提示符”或“ Git Bash”设置为默认值。
-
选定的环境显示在VS Code状态栏的左侧,并注意“(venv)”指示器,该指示器告诉您您正在使用虚拟环境:
-
通过在VS Code终端中运行以下命令之一,在虚拟环境中安装Django:
<span style="color:#333333"><code><span style="color:#000000">python -m pip install django</span></code></span>
现在,您已经可以使用一个独立的环境来编写Django代码。当您使用VS代码会自动激活的环境中创建新的集成终端:终端。如果你打开一个单独的命令提示符或终端,运行启动环境source env/bin/activate
(Linux的/ MacOS的)或env\scripts\activate
(Windows)中。您知道当命令提示符开头显示(env)时环境已激活。
创建并运行一个最小的Django应用程序#
用Django术语,“ Django项目”由几个站点级配置文件以及一个或多个“应用程序”组成,您将它们部署到Web主机以创建完整的Web应用程序。Django项目可以包含多个应用程序,每个应用程序通常在项目中具有独立的功能,而同一个应用程序可以在多个Django项目中。就应用而言,它只是一个Python包,遵循Django期望的某些约定。
然后,要创建一个最小的Django应用程序,必须先创建Django项目作为应用程序的容器,然后再创建应用程序本身。出于这两个目的,您使用Django管理实用程序django-admin
,该实用程序是在安装Django软件包时安装的。
创建Django项目#
-
在激活了虚拟环境的VS Code终端中,运行以下命令:
<span style="color:#333333"><code><span style="color:#000000">django-admin startproject web_project </span><span style="color:#795e26">.</span></code></span>
该
startproject
命令假定(.
最后使用)当前文件夹是您的项目文件夹,并在其中创建以下内容:-
manage.py
:项目的Django命令行管理实用程序。您可以使用来为项目运行管理命令python manage.py <command> [options]
。 -
名为的子文件夹
web_project
,其中包含以下文件:__init__.py
:一个空文件,告诉Python该文件夹是Python软件包。wsgi.py
:与WSGI兼容的Web服务器为您的项目提供服务的入口点。通常,此文件保持原样,因为它为生产Web服务器提供了挂钩。settings.py
:包含Django项目的设置,您可以在开发Web应用程序的过程中对其进行修改。urls.py
:包含Django项目的目录,您也可以在开发过程中对其进行修改。
-
-
要验证Django项目,请确保您的虚拟环境已激活,然后使用命令启动Django的开发服务器
python manage.py runserver
。服务器在默认端口8000上运行,并且您会在终端窗口中看到类似于以下输出的输出:<span style="color:#333333"><code>Performing system checks... System check identified no issues (0 silenced). September 05, 2018 - 14:33:31 Django version 2.1.1, using settings 'web_project.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK. </code></span>
首次运行服务器时,它将在文件中创建一个默认的SQLite数据库,该数据库
db.sqlite3
用于开发目的,但可用于生产少量Web应用程序。另外,Django的内置Web服务器仅用于本地开发目的。但是,当您部署到Web主机时,Django会改为使用主机的Web服务器。wsgi.py
Django项目中的模块负责连接到生产服务器。如果要使用默认端口以外的其他端口8000,请在命令行上指定端口号,例如
python manage.py runserver 5000
。 -
Ctrl +单击的
http://127.0.0.1:8000/
终端输出窗口的网址,打开您的默认浏览到该地址。如果正确安装了Django并且项目有效,那么您会看到下面显示的默认页面。VS Code终端输出窗口还显示服务器日志。 -
完成后,关闭浏览器窗口,并按Ctrl + C的VS Code停止服务器,如终端输出窗口中所示。
创建Django应用#
-
在激活了虚拟环境的VS Code终端中,
startapp
在项目文件夹(manage.py
所在的位置)中运行管理实用程序的命令:<span style="color:#333333"><code><span style="color:#000000">python manage.py startapp hello</span></code></span>
该命令将创建一个名为的文件夹
hello
,其中包含许多代码文件和一个子文件夹。其中,您经常使用views.py
(包含定义Web应用程序中页面的功能)和models.py
(包含定义数据对象的类)。该migrations
文件夹由Django的管理实用程序用来管理数据库版本,如本教程后面所述。还有文件apps.py
(应用程序配置),admin.py
(用于创建管理界面)和tests.py
(用于测试),在此不介绍。 -
进行修改
hello/views.py
以匹配以下代码,从而为应用程序的主页创建一个视图:<span style="color:#333333"><code><span style="color:#0000ff">from</span><span style="color:#000000"> django.http </span><span style="color:#0000ff">import</span><span style="color:#000000"> HttpResponse</span> <span style="color:#0000ff">def</span> <span style="color:#795e26">home</span><span style="color:#000000">(</span><span style="color:#001080">request</span><span style="color:#000000">):</span> <span style="color:#0000ff">return</span><span style="color:#000000"> HttpResponse(</span><span style="color:#a31515">"Hello, Django!"</span><span style="color:#000000">)</span></code></span>
-
创建一个文件,
hello/urls.py
其内容如下。在该urls.py
文件中,您可以指定用于将不同的URL路由到其相应视图的模式。以下代码包含一种将应用(""
)的根URL映射到views.home
刚添加到的函数的途径hello/views.py
:<span style="color:#333333"><code><span style="color:#0000ff">from</span><span style="color:#000000"> django.urls </span><span style="color:#0000ff">import</span><span style="color:#000000"> path</span> <span style="color:#0000ff">from</span><span style="color:#000000"> hello </span><span style="color:#0000ff">import</span><span style="color:#000000"> views</span> <span style="color:#000000">urlpatterns = [</span> <span style="color:#000000"> path(</span><span style="color:#a31515">""</span><span style="color:#000000">, views.home, </span><span style="color:#001080">name</span><span style="color:#000000">=</span><span style="color:#a31515">"home"</span><span style="color:#000000">),</span> <span style="color:#000000">]</span></code></span>
-
该
web_project
文件夹还包含一个urls.py
文件,在该文件中实际处理URL路由。打开web_project/urls.py
并修改它,使其与以下代码匹配(如果需要,可以保留说明性注释)。此代码提取应用程序的hello/urls.py
usingdjango.urls.include
,从而使应用程序的路由包含在应用程序内。当一个项目包含多个应用程序时,这种分离非常有用。<span style="color:#333333"><code><span style="color:#0000ff">from</span><span style="color:#000000"> django.contrib </span><span style="color:#0000ff">import</span><span style="color:#000000"> admin</span> <span style="color:#0000ff">from</span><span style="color:#000000"> django.urls </span><span style="color:#0000ff">import</span><span style="color:#000000"> include, path</span> <span style="color:#000000">urlpatterns = [</span> <span style="color:#000000"> path(</span><span style="color:#a31515">""</span><span style="color:#000000">, include(</span><span style="color:#a31515">"hello.urls"</span><span style="color:#000000">)),</span> <span style="color:#000000">]</span></code></span>
-
使用Ctrl + Shift+S保存所有修改的文件。
-
在VS Code终端中,再次激活虚拟环境,使用来运行开发服务器
python manage.py runserver
并打开浏览器http://127.0.0.1:8000/
以查看呈现“ Hello,Django”的页面。
创建调试启动配置文件#
您可能已经在想,是否有一种更简便的方法来运行服务器并测试应用程序而无需python manage.py runserver
每次都键入。幸运的是,有!您可以在VS Code中创建自定义的启动配置文件,该配置文件还用于不可避免的调试。
-
切换到VS Code中的“运行”视图(使用左侧活动栏)。在“运行”视图的顶部,齿轮图标上可能会显示“无配置”和警告点。这两个指示符都表示您还没有
launch.json
包含调试配置的文件: -
选择齿轮图标,并等待几秒钟,以便VS Code创建并打开
launch.json
文件。(如果使用的是VS Code的旧版本,则可能会提示您提供调试器目标列表,在这种情况下,请从列表中选择Python。)该launch.json
文件包含许多调试配置,每个调试配置都是单独的JSON。configuration
数组中的对象。 -
向下滚动并检查名称为“ Python:Django”的配置:
<span style="color:#333333"><code><span style="color:#000000">{</span> <span style="color:#0451a5">"name"</span><span style="color:#000000">: </span><span style="color:#a31515">"Python: Django"</span><span style="color:#000000">,</span> <span style="color:#0451a5">"type"</span><span style="color:#000000">: </span><span style="color:#a31515">"python"</span><span style="color:#000000">,</span> <span style="color:#0451a5">"request"</span><span style="color:#000000">: </span><span style="color:#a31515">"launch"</span><span style="color:#000000">,</span> <span style="color:#0451a5">"program"</span><span style="color:#000000">: </span><span style="color:#a31515">"${workspaceFolder}/manage.py"</span><span style="color:#000000">,</span> <span style="color:#0451a5">"console"</span><span style="color:#000000">: </span><span style="color:#a31515">"integratedTerminal"</span><span style="color:#000000">,</span> <span style="color:#0451a5">"args"</span><span style="color:#000000">: [</span> <span style="color:#a31515">"runserver"</span><span style="color:#000000">,</span> <span style="color:#000000"> ],</span> <span style="color:#0451a5">"django"</span><span style="color:#000000">: </span><span style="color:#0000ff">true</span> <span style="color:#000000">},</span></code></span>
此配置告诉VS Code
"${workspaceFolder}/manage.py"
使用选定的Python解释器和args
列表中的参数运行。然后,使用此配置启动VS Code调试器与python manage.py runserver
在激活的虚拟环境中在VS Code终端中运行相同。(您可以添加一个端口号就像"5000"
到args
,如果需要的话。)的"django": true
条目还告诉VS代码来启用的Django的页面模板,您将在本教程后面看到调试。 -
保存
launch.json
(Ctrl + S)。在调试配置下拉列表(显示为Python:Current File)中,选择Python:Django配置: -
通过选择“运行” >“开始调试”菜单命令或选择列表旁边的绿色“开始调试”箭头(F5),测试配置:
-
http://127.0.0.1:8000/
在终端输出窗口中,按住Ctrl键并单击URL,以打开浏览器,并查看该应用程序是否正常运行。 -
完成后,关闭浏览器并停止调试器。要停止调试器,请使用“停止”工具栏按钮(红色方框)或“运行” >“停止调试”命令(Shift + F5)。
-
现在,您可以随时使用“运行” >“开始调试”来测试应用程序,这还具有自动保存所有修改后的文件的优势。
调试#
调试使您有机会在特定的代码行上暂停正在运行的程序。程序暂停后,您可以检查变量,在Debug Console面板中运行代码,或者利用Debugging上描述的功能。运行调试器还会在调试会话开始之前自动保存所有已修改的文件。
开始之前:通过使用终端中的Ctrl + C,确保已在最后一节的结尾停止了正在运行的应用程序。如果您让应用程序在一个终端上运行,它将继续拥有该端口。结果,当您使用相同的端口在调试器中运行该应用程序时,原始正在运行的应用程序会处理所有请求,并且您将看不到正在调试的应用程序中的任何活动,并且该程序不会在断点处停止。换句话说,如果调试器似乎无法正常工作,请确保没有其他应用程序实例在运行。
-
在中
hello/urls.py
,将路由添加到urlpatterns
列表:<span style="color:#333333"><code><span style="color:#000000">path(</span><span style="color:#a31515">"hello/<name>"</span><span style="color:#000000">, views.hello_there, </span><span style="color:#001080">name</span><span style="color:#000000">=</span><span style="color:#a31515">"hello_there"</span><span style="color:#000000">),</span></code></span>
的第一个参数
path
定义了路由“ hello /”,该路由接受名为name的可变字符串。该字符串将传递到views.hello_there
的第二个参数中指定的函数path
。URL路由区分大小写。例如,路线
/hello/<name>
不同于/Hello/<name>
。如果您希望同一个视图函数同时处理这两个视图,请为每个变量定义路径。 -
用
views.py
以下代码替换的内容,以定义hello_there
可在调试器中逐步执行的功能:<span style="color:#333333"><code><span style="color:#0000ff">import</span><span style="color:#000000"> re</span> <span style="color:#0000ff">from</span><span style="color:#000000"> datetime </span><span style="color:#0000ff">import</span><span style="color:#000000"> datetime</span> <span style="color:#0000ff">from</span><span style="color:#000000"> django.http </span><span style="color:#0000ff">import</span><span style="color:#000000"> HttpResponse</span> <span style="color:#0000ff">def</span> <span style="color:#795e26">home</span><span style="color:#000000">(</span><span style="color:#001080">request</span><span style="color:#000000">):</span> <span style="color:#0000ff">return</span><span style="color:#000000"> HttpResponse(</span><span style="color:#a31515">"Hello, Django!"</span><span style="color:#000000">)</span> <span style="color:#0000ff">def</span> <span style="color:#795e26">hello_there</span><span style="color:#000000">(</span><span style="color:#001080">request</span><span style="color:#000000">, </span><span style="color:#001080">name</span><span style="color:#000000">):</span> <span style="color:#000000"> now = datetime.now()</span> <span style="color:#000000"> formatted_now = now.strftime(</span><span style="color:#a31515">"%A, </span><span style="color:#0000ff">%d</span><span style="color:#a31515"> %B, %Y at </span><span style="color:#0000ff">%X</span><span style="color:#a31515">"</span><span style="color:#000000">)</span> <span style="color:#008000"># Filter the name argument to letters only using regular expressions. URL arguments</span> <span style="color:#008000"># can contain arbitrary text, so we restrict to safe characters only.</span> <span style="color:#000000"> match_object = re.match(</span><span style="color:#a31515">"[a-zA-Z]+"</span><span style="color:#000000">, name)</span> <span style="color:#0000ff">if</span><span style="color:#000000"> match_object:</span> <span style="color:#000000"> clean_name = match_object.group(</span><span style="color:#098658">0</span><span style="color:#000000">)</span> <span style="color:#0000ff">else</span><span style="color:#000000">:</span> <span style="color:#000000"> clean_name = </span><span style="color:#a31515">"Friend"</span> <span style="color:#000000"> content = </span><span style="color:#a31515">"Hello there, "</span><span style="color:#000000"> + clean_name + </span><span style="color:#a31515">"! It's "</span><span style="color:#000000"> + formatted_now</span> <span style="color:#0000ff">return</span><span style="color:#000000"> HttpResponse(content)</span></code></span>
name
URL路由中定义的变量作为hello_there
函数的参数给出。如代码注释中所述,请始终过滤用户提供的任意信息,以避免对您的应用程序进行各种攻击。在这种情况下,代码将name参数过滤为仅包含字母,从而避免了注入控制字符,HTML等。(在下一节中使用模板时,Django会执行自动过滤,并且您不需要此代码。) -
通过执行以下任一操作,在
hello_there
函数(now = datetime.now()
)的第一行代码处设置一个断点:- 将光标放在该行上,按F9,或,
- 将光标放在该行上,选择“运行” >“切换断点”菜单命令,或者,
- 直接在行号左侧的空白处单击(将鼠标悬停在该行上时会出现一个淡红色的点)。
断点在左边距中显示为红点:
-
通过选择“运行” >“开始调试”菜单命令或选择列表旁边的绿色“开始调试”箭头(F5),启动调试器:
观察状态栏的颜色更改以指示调试:
VS Code中还会出现一个调试工具栏(如下所示),其中包含以下顺序的命令:暂停(或继续,F5),跳过(F10),进入(F11),退出(Shift + F11),重新启动(Ctrl + Shift + F5),然后停止(Shift + F5)。有关每个命令的说明,请参见VS代码调试。
-
输出显示在“ Python调试控制台”终端中。打开浏览器并导航到
http://127.0.0.1:8000/hello/VSCode
。在页面呈现之前,VS Code在您设置的断点处暂停程序。断点上的黄色小箭头表示这是要运行的下一行代码。 -
使用Step Over运行
now = datetime.now()
语句。 -
在“ VS代码”窗口的左侧,您会看到一个“变量”窗格,其中显示了局部变量(例如)
now
以及参数(例如)name
。下面是Watch,Call Stack和Breakpoints的窗格(有关详细信息,请参见VS Code调试)。在“本地”部分中,尝试扩展其他值。您也可以双击值(或使用F2)来修改它们。now
但是,更改诸如之类的变量可能会破坏程序。开发人员通常仅在代码没有产生正确的值时才进行更改,以更正正确的值。 -
程序暂停后,“调试控制台”面板(与“终端”面板中的“ Python调试控制台”不同)使您可以试验表达式,并使用程序的当前状态尝试一些代码。例如,一旦您跳过了该行
now = datetime.now()
,就可以尝试使用不同的日期/时间格式。在编辑器中,选择显示为的代码now.strftime("%A, %d %B, %Y at %X")
,然后右键单击并选择Debug:Evaluate将该代码发送到运行它的调试控制台:<span style="color:#333333"><code><span style="color:#000000">now.strftime(</span><span style="color:#a31515">"%A, %d %B, %Y at %X"</span><span style="color:#000000">)</span> <span style="color:#a31515">'Friday, 07 September, 2018 at 07:46:32'</span></code></span>
提示:调试控制台还显示了应用程序中可能未显示在终端中的异常。例如,如果在“运行”视图的“调用堆栈”区域中看到“在异常时暂停”消息,请切换到调试控制台以查看异常消息。
-
将该行复制到调试控制台底部的>提示符,然后尝试更改格式:
<span style="color:#333333"><code><span style="color:#000000">now.strftime(</span><span style="color:#a31515">"%a, %d %B, %Y at %X"</span><span style="color:#000000">)</span> <span style="color:#a31515">'Fri, 07 September, 2018 at 07:46:32'</span> <span style="color:#000000">now.strftime(</span><span style="color:#a31515">"%a, %d %b, %Y at %X"</span><span style="color:#000000">)</span> <span style="color:#a31515">'Fri, 07 Sep, 2018 at 07:46:32'</span> <span style="color:#000000">now.strftime(</span><span style="color:#a31515">"%a, %d %b, %y at %X"</span><span style="color:#000000">)</span> <span style="color:#a31515">'Fri, 07 Sep, 18 at 07:46:32'</span></code></span>
注意:如果看到自己喜欢的更改,则可以在调试会话期间将其复制并粘贴到编辑器中。但是,只有重新启动调试器后,这些更改才会应用。
-
如果需要,可以再执行几行代码,然后选择Continue(F5)以使程序运行。浏览器窗口显示结果:
-
完成后,关闭浏览器并停止调试器。要停止调试器,请使用“停止”工具栏按钮(红色方框)或“运行” >“停止调试”命令(Shift + F5)。
提示:要使其更容易重复浏览至特定URL
http://127.0.0.1:8000/hello/VSCode
,请使用views.py
。该URL出现在VS Code终端中,您可以在其中使用Ctrl + click在浏览器中将其打开。
转到定义和PEEK定义命令#
在使用Django或任何其他库的过程中,您可能需要检查这些库本身中的代码。VS Code提供了两个方便的命令,它们可以直接导航到任何代码中的类和其他对象的定义:
-
“转到定义”从您的代码跳转到定义对象的代码。例如,在中
views.py
,右键单击HttpResponse
该home
函数,然后选择Go to Definition(或使用F12),它会导航到Django库中的类定义。 -
偷看定义(Alt + F12,也在右键单击上下文菜单上)相似,但是直接在编辑器中显示类定义(在编辑器窗口中留出空间以避免混淆任何代码)。按Escape键关闭“窥视”窗口,或使用右上角的x。
使用模板来渲染页面#
到目前为止,您在本教程中创建的应用程序仅通过Python代码生成纯文本网页。尽管可以直接在代码中生成HTML,但开发人员避免了这种做法,因为它会使应用程序受到跨站点脚本(XSS)攻击。hello_there
例如,在本教程的功能中,人们可能会考虑使用诸如之类的代码来格式化输出content = "<h1>Hello there, " + clean_name + "!</h1>
,其中将结果content
直接提供给浏览器。此漏洞使攻击者可以在URL中放置恶意HTML(包括JavaScript代码),该URL最终clean_name
在浏览器中运行。
更好的做法是通过使用模板将HTML完全排除在代码之外,这样您的代码仅与数据值有关,而与呈现无关。
在Django中,模板是一个HTML文件,其中包含代码在运行时提供的值的占位符。然后,Django模板引擎会在呈现页面时进行替换,并提供自动转义以防止XSS攻击(也就是说,如果您尝试在数据值中使用HTML,您将看到HTML仅呈现为纯文本)。因此,代码仅与数据值有关,而模板仅与标记有关。Django模板提供了灵活的选项,例如模板继承,它允许您定义具有通用标记的基本页面,然后在该基础上添加特定于页面的添加。
在本节中,您将从使用模板创建单个页面开始。在随后的部分中,您将应用配置为提供静态文件,然后为该应用创建多个页面,每个页面均包含基本模板中的导航栏。Django模板还支持控制流和迭代,如本教程后面在模板调试的上下文中所见。
-
在
web_project/settings.py
文件中,找到INSTALLED_APPS
列表并添加以下条目,以确保项目了解应用程序,以便可以处理模板:<span style="color:#333333"><code><span style="color:#a31515">'hello'</span><span style="color:#000000">,</span></code></span>
-
在该
hello
文件夹内,创建一个名为的文件夹templates
,然后创建另一个hello
与应用程序名称匹配的子文件夹(此两层文件夹结构是典型的Django约定)。 -
在
templates/hello
文件夹中,创建一个文件hello_there.html
,其内容如下。该模板包含两个占位符,分别代表成对的数据值“ name”和“ date”,用大括号对{{
和来表示}}
。所有其他不变文本以及格式标记(例如<strong>
)都是模板的一部分。如您所见,模板占位符还可以包括格式,管道|
符号后的表达式,在这种情况下,使用Django的内置日期过滤器和时间过滤器。然后,该代码仅需要传递datetime值,而不需要传递预先格式化的字符串:<span style="color:#333333"><code><span style="color:#800000"><!</span><span style="color:#000000">DOCTYPE html</span><span style="color:#800000">></span> <span style="color:#800000"><html></span> <span style="color:#800000"><head></span> <span style="color:#800000"><meta</span> <span style="color:#ff0000">charset</span><span style="color:#000000">=</span><span style="color:#0000ff">"utf-8"</span><span style="color:#800000"> /></span> <span style="color:#800000"><title></span><span style="color:#000000">Hello, Django</span><span style="color:#800000"></title></span> <span style="color:#800000"></head></span> <span style="color:#800000"><body></span> <span style="color:#800000"><strong></span><span style="color:#000000">Hello there, {{ name }}!</span><span style="color:#800000"></strong></span><span style="color:#000000"> It's {{ date | date:"l, d F, Y" }} at {{ date | time:"H:i:s" }}</span> <span style="color:#800000"></body></span> <span style="color:#800000"></html></span></code></span>
-
在的顶部
views.py
,添加以下导入语句:<span style="color:#333333"><code><span style="color:#0000ff">from</span><span style="color:#000000"> django.shortcuts </span><span style="color:#0000ff">import</span><span style="color:#000000"> render</span></code></span>
-
同样
views.py
,在hello_there
函数中修改使用django.shortcuts.render
方法来加载模板并提供模板上下文。上下文是在模板中使用的变量集。该render
函数接受请求对象,然后是相对于templates
folder的模板的路径,然后是上下文对象。(开发人员通常使用与模板相同的功能来命名模板,但是不需要匹配名称,因为您始终在代码中引用确切的文件名。)<span style="color:#333333"><code><span style="color:#0000ff">def</span> <span style="color:#795e26">hello_there</span><span style="color:#000000">(</span><span style="color:#001080">request</span><span style="color:#000000">, </span><span style="color:#001080">name</span><span style="color:#000000">):</span> <span style="color:#0000ff">return</span><span style="color:#000000"> render(</span> <span style="color:#000000"> request,</span> <span style="color:#a31515">'hello/hello_there.html'</span><span style="color:#000000">,</span> <span style="color:#000000"> {</span> <span style="color:#a31515">'name'</span><span style="color:#000000">: name,</span> <span style="color:#a31515">'date'</span><span style="color:#000000">: datetime.now()</span> <span style="color:#000000"> }</span> <span style="color:#000000"> )</span></code></span>
您可以看到该代码现在更加简单,并且仅涉及数据值,因为标记和格式都包含在模板中。
-
启动程序(使用Ctrl + F5在调试器内部或外部),导航到/ hello / name URL,并观察结果。
-
还可以尝试使用一个名称导航到/ hello / name URL,例如,
<a%20value%20that%20could%20be%20HTML>
以查看Django在工作时的自动转义。“名称”值在浏览器中显示为纯文本,而不是呈现实际元素。
提供静态文件#
静态文件是您的Web应用针对某些请求按原样返回的内容,例如CSS文件。提供静态文件要求INSTALLED_APPS
列表中settings.py
包含django.contrib.staticfiles
,默认情况下包含该列表。
在Django中提供静态文件是一种艺术,特别是在部署到生产环境时。这里显示的是一种与Django开发服务器以及gunicorn等生产服务器一起使用的简单方法。但是,对静态文件的完整处理超出了本教程的范围,因此,有关更多信息,请参阅Django文档中的管理静态文件。
在生产中,您还需要设置DEBUG=False
in settings.py
,这在使用容器时需要进行一些额外的工作。有关详细信息,请参见第13期。
为应用准备好静态文件#
-
在项目的中
web_project/urls.py
,添加以下import
语句:<span style="color:#333333"><code><span style="color:#0000ff">from</span><span style="color:#000000"> django.contrib.staticfiles.urls </span><span style="color:#0000ff">import</span><span style="color:#000000"> staticfiles_urlpatterns</span></code></span>
-
在同一文件中,在行末添加以下行,其中将标准静态文件URL包含到项目可识别的列表中:
<span style="color:#333333"><code><span style="color:#000000">urlpatterns += staticfiles_urlpatterns()</span></code></span>
请参阅静态文件的模板#
-
在
hello
文件夹中,创建一个名为的文件夹static
。 -
在
static
文件夹中,创建一个名为的子文件夹,该子文件夹hello
与应用程序名称匹配。此额外子文件夹的原因是,当您将Django项目部署到生产服务器时,您将所有静态文件收集到一个文件夹中,然后由专用静态文件服务器提供服务。该
static/hello
子文件夹,这样可确保收集到的应用程序的静态文件的时候,他们在一个应用程序特定的子文件夹,不会碰撞在同一个项目的其他应用程序文件。 -
在
static/hello
文件夹中,创建一个site.css
包含以下内容的文件。输入此代码后,还请注意VS Code为CSS文件提供的语法突出显示,包括颜色预览。<span style="color:#333333"><code><span style="color:#800000">.message</span><span style="color:#000000"> {</span> <span style="color:#ff0000">font-weight</span><span style="color:#000000">: </span><span style="color:#098658">600</span><span style="color:#000000">;</span> <span style="color:#ff0000">color</span><span style="color:#000000">: </span><span style="color:#0451a5">blue</span><span style="color:#000000">;</span> <span style="color:#000000">}</span></code></span>
-
在中
templates/hello/hello_there.html
,在<title>
元素之后添加以下几行。该{% load static %}
标记是一个自定义Django模板标记集,它使您可以{% static %}
用来引用样式表之类的文件。<span style="color:#333333"><code><span style="color:#000000">{% load static %}</span> <span style="color:#800000"><link</span> <span style="color:#ff0000">rel</span><span style="color:#000000">=</span><span style="color:#0000ff">"stylesheet"</span> <span style="color:#ff0000">type</span><span style="color:#000000">=</span><span style="color:#0000ff">"text/css"</span> <span style="color:#ff0000">href</span><span style="color:#000000">=</span><span style="color:#0000ff">"{% static 'hello/site.css' %}"</span><span style="color:#800000"> /></span></code></span>
-
同样在中
templates/hello/hello_there.html
,将content<body>
元素替换为使用message
样式而不是<strong>
标签的以下标记:<span style="color:#333333"><code><span style="color:#800000"><span</span> <span style="color:#ff0000">class</span><span style="color:#000000">=</span><span style="color:#0000ff">"message"</span><span style="color:#800000">></span><span style="color:#000000">Hello, there {{ name }}!</span><span style="color:#800000"></span></span><span style="color:#000000"> It's {{ date | date:'l, d F, Y' }} at {{ date | time:'H:i:s' }}.</span></code></span>
-
运行该应用程序,导航到/ hello / name URL,然后观察该消息呈蓝色显示。完成后,停止应用程序。
使用collectstatic命令#
对于生产部署,通常使用以下python manage.py collectstatic
命令将应用程序中的所有静态文件收集到一个文件夹中。然后,您可以使用专用的静态文件服务器来提供这些文件,这通常可以提高整体性能。尽管在Django开发服务器上运行时不使用该集合,但以下步骤说明了如何进行该集合。
-
在中
web_project/settings.py
,添加以下行,该行定义使用该collectstatic
命令时收集静态文件的位置:<span style="color:#333333"><code><span style="color:#000000">STATIC_ROOT = os.path.join(BASE_DIR, </span><span style="color:#a31515">'static_collected'</span><span style="color:#000000">)</span></code></span>
-
在终端中,运行命令
python manage.py collectstatic
并观察该命令将hello/site.css
其复制到顶层static_collected
文件夹中manage.py
。 -
实际上,在
collectstatic
更改静态文件时以及部署到生产中之前,都可以运行。
创建扩展基本模板多个模板#
因为大多数Web应用程序具有多个页面,并且由于这些页面通常共享许多公共元素,所以开发人员将这些公共元素分离为一个基本页面模板,其他页面模板随后对其进行了扩展。(这也称为模板继承,这意味着扩展页面将从基础页面继承元素。)
另外,由于您可能会创建许多扩展相同模板的页面,因此在VS Code中创建代码片段非常有用,您可以使用该代码片段快速初始化新的页面模板。摘要帮助您避免繁琐且容易出错的复制粘贴操作。
以下各节介绍了此过程的不同部分。
创建基础页面模板和样式#
Django中的基本页面模板包含一组页面的所有共享部分,包括对CSS文件,脚本文件等的引用。基本模板还定义了一个或多个块标签,其中包含扩展模板应覆盖的内容。块标记由划定{% block <name> %}
并{% endblock %}
在基座模板和扩展模板两者。
以下步骤演示了如何创建基本模板。
-
在
templates/hello
文件夹中,创建一个layout.html
包含以下内容的文件,其中包含名为“ title”和“ content”的块。如您所见,标记定义了一个简单的导航栏结构,该结构带有指向“主页”,“关于”和“联系人”页面的链接,这些链接将在后面的部分中创建。请注意,使用Django的{% url %}
标记通过相应的URL模式的名称而不是相对路径来引用其他页面。<span style="color:#333333"><code><span style="color:#800000"><!</span><span style="color:#000000">DOCTYPE html</span><span style="color:#800000">></span> <span style="color:#800000"><html></span> <span style="color:#800000"><head></span> <span style="color:#800000"><meta</span> <span style="color:#ff0000">charset</span><span style="color:#000000">=</span><span style="color:#0000ff">"utf-8"</span><span style="color:#800000">/></span> <span style="color:#800000"><title></span><span style="color:#000000">{% block title %}{% endblock %}</span><span style="color:#800000"></title></span> <span style="color:#000000"> {% load static %}</span> <span style="color:#800000"><link</span> <span style="color:#ff0000">rel</span><span style="color:#000000">=</span><span style="color:#0000ff">"stylesheet"</span> <span style="color:#ff0000">type</span><span style="color:#000000">=</span><span style="color:#0000ff">"text/css"</span> <span style="color:#ff0000">href</span><span style="color:#000000">=</span><span style="color:#0000ff">"{% static 'hello/site.css' %}"</span><span style="color:#800000">/></span> <span style="color:#800000"></head></span> <span style="color:#800000"><body></span> <span style="color:#800000"><div</span> <span style="color:#ff0000">class</span><span style="color:#000000">=</span><span style="color:#0000ff">"navbar"</span><span style="color:#800000">></span> <span style="color:#800000"><a</span> <span style="color:#ff0000">href</span><span style="color:#000000">=</span><span style="color:#0000ff">"{% url 'home' %}"</span> <span style="color:#ff0000">class</span><span style="color:#000000">=</span><span style="color:#0000ff">"navbar-brand"</span><span style="color:#800000">></span><span style="color:#000000">Home</span><span style="color:#800000"></a></span> <span style="color:#800000"><a</span> <span style="color:#ff0000">href</span><span style="color:#000000">=</span><span style="color:#0000ff">"{% url 'about' %}"</span> <span style="color:#ff0000">class</span><span style="color:#000000">=</span><span style="color:#0000ff">"navbar-item"</span><span style="color:#800000">></span><span style="color:#000000">About</span><span style="color:#800000"></a></span> <span style="color:#800000"><a</span> <span style="color:#ff0000">href</span><span style="color:#000000">=</span><span style="color:#0000ff">"{% url 'contact' %}"</span> <span style="color:#ff0000">class</span><span style="color:#000000">=</span><span style="color:#0000ff">"navbar-item"</span><span style="color:#800000">></span><span style="color:#000000">Contact</span><span style="color:#800000"></a></span> <span style="color:#800000"></div></span> <span style="color:#800000"><div</span> <span style="color:#ff0000">class</span><span style="color:#000000">=</span><span style="color:#0000ff">"body-content"</span><span style="color:#800000">></span> <span style="color:#000000"> {% block content %}</span> <span style="color:#000000"> {% endblock %}</span> <span style="color:#800000"><hr</span><span style="color:#000000">/</span><span style="color:#800000">></span> <span style="color:#800000"><footer></span> <span style="color:#800000"><p></span><span style="color:#0000ff">©</span><span style="color:#000000"> 2018</span><span style="color:#800000"></p></span> <span style="color:#800000"></footer></span> <span style="color:#800000"></div></span> <span style="color:#800000"></body></span> <span style="color:#800000"></html></span></code></span>
-
将以下样式添加到
static/hello/site.css
现有“消息”样式下方,然后保存文件。(本演练并不试图演示响应式设计;这些样式只会产生相当有趣的结果。)<span style="color:#333333"><code><span style="color:#800000">.navbar</span><span style="color:#000000"> {</span> <span style="color:#ff0000">background-color</span><span style="color:#000000">: </span><span style="color:#0451a5">lightslategray</span><span style="color:#000000">;</span> <span style="color:#ff0000">font-size</span><span style="color:#000000">: </span><span style="color:#098658">1em</span><span style="color:#000000">;</span> <span style="color:#ff0000">font-family</span><span style="color:#000000">: </span><span style="color:#a31515">'Trebuchet MS'</span><span style="color:#000000">, </span><span style="color:#a31515">'Lucida Sans Unicode'</span><span style="color:#000000">, </span><span style="color:#a31515">'Lucida Grande'</span><span style="color:#000000">, </span><span style="color:#a31515">'Lucida Sans'</span><span style="color:#000000">, </span><span style="color:#0451a5">Arial</span><span style="color:#000000">, </span><span style="color:#0451a5">sans-serif</span><span style="color:#000000">;</span> <span style="color:#ff0000">color</span><span style="color:#000000">: </span><span style="color:#0451a5">white</span><span style="color:#000000">;</span> <span style="color:#ff0000">padding</span><span style="color:#000000">: </span><span style="color:#098658">8px</span> <span style="color:#098658">5px</span> <span style="color:#098658">8px</span> <span style="color:#098658">5px</span><span style="color:#000000">;</span> <span style="color:#000000">}</span> <span style="color:#800000">.navbar</span> <span style="color:#800000">a</span><span style="color:#000000"> {</span> <span style="color:#ff0000">text-decoration</span><span style="color:#000000">: </span><span style="color:#0451a5">none</span><span style="color:#000000">;</span> <span style="color:#ff0000">color</span><span style="color:#000000">: </span><span style="color:#0451a5">inherit</span><span style="color:#000000">;</span> <span style="color:#000000">}</span> <span style="color:#800000">.navbar-brand</span><span style="color:#000000"> {</span> <span style="color:#ff0000">font-size</span><span style="color:#000000">: </span><span style="color:#098658">1.2em</span><span style="color:#000000">;</span> <span style="color:#ff0000">font-weight</span><span style="color:#000000">: </span><span style="color:#098658">600</span><span style="color:#000000">;</span> <span style="color:#000000">}</span> <span style="color:#800000">.navbar-item</span><span style="color:#000000"> {</span> <span style="color:#ff0000">font-variant</span><span style="color:#000000">: </span><span style="color:#0451a5">small-caps</span><span style="color:#000000">;</span> <span style="color:#ff0000">margin-left</span><span style="color:#000000">: </span><span style="color:#098658">30px</span><span style="color:#000000">;</span> <span style="color:#000000">}</span> <span style="color:#800000">.body-content</span><span style="color:#000000"> {</span> <span style="color:#ff0000">padding</span><span style="color:#000000">: </span><span style="color:#098658">5px</span><span style="color:#000000">;</span> <span style="color:#ff0000">font-family</span><span style="color:#000000">:</span><span style="color:#a31515">'Segoe UI'</span><span style="color:#000000">, </span><span style="color:#0451a5">Tahoma</span><span style="color:#000000">, Geneva, </span><span style="color:#0451a5">Verdana</span><span style="color:#000000">, </span><span style="color:#0451a5">sans-serif</span><span style="color:#000000">;</span> <span style="color:#000000">}</span></code></span>
您可以在此时运行该应用程序,但是由于您没有在任何地方使用基本模板,也没有更改任何代码文件,因此结果与上一步相同。完成其余部分以查看最终效果。
创建代码片段#
由于您在下一节中创建的三个页面可以扩展layout.html
,因此可以节省创建代码片段的时间,该代码片段可以使用对基础模板的适当引用来初始化新模板文件。代码段可从单一来源提供一致的代码段,从而避免了在使用现有代码中的复制粘贴时可能蔓延的错误。
-
在VS Code中,选择文件(Windows / Linux)或Code(macOS)菜单,然后选择首选项>用户片段。
-
在出现的列表中,选择html。(如果您之前创建过代码段,则该选项在列表的“现有代码段”中可能显示为“ html.json” 。)
-
VS代码打开后
html.json
,在现有花括号内添加以下代码。(此处未显示的解释性注释描述了一些细节,例如该$0
行如何指示VS代码在插入代码段后将光标放置在何处):<span style="color:#333333"><code><span style="color:#a31515">"Django Tutorial: template extending layout.html"</span><span style="color:#000000">: {</span> <span style="color:#0451a5">"prefix"</span><span style="color:#000000">: </span><span style="color:#a31515">"djextlayout"</span><span style="color:#000000">,</span> <span style="color:#0451a5">"body"</span><span style="color:#000000">: [</span> <span style="color:#a31515">"{% extends </span><span style="color:#ee0000">\"</span><span style="color:#a31515">hello/layout.html</span><span style="color:#ee0000">\"</span><span style="color:#a31515"> %}"</span><span style="color:#000000">,</span> <span style="color:#a31515">"{% block title %}"</span><span style="color:#000000">,</span> <span style="color:#a31515">"$0"</span><span style="color:#000000">,</span> <span style="color:#a31515">"{% endblock %}"</span><span style="color:#000000">,</span> <span style="color:#a31515">"{% block content %}"</span><span style="color:#000000">,</span> <span style="color:#a31515">"{% endblock %}"</span> <span style="color:#000000"> ],</span> <span style="color:#0451a5">"description"</span><span style="color:#000000">: </span><span style="color:#a31515">"Boilerplate template that extends layout.html"</span> <span style="color:#000000">},</span></code></span>
-
保存
html.json
文件(Ctrl + S)。 -
现在,每当您开始输入代码段的前缀(例如)时
djext
,VS Code就会将代码段作为自动完成选项提供,如下一节所示。您还可以使用“插入代码段”命令从菜单中选择一个代码段。
使用代码片段在网页中加入#
使用适当的代码段,您可以快速创建“主页”,“关于”和“联系人”页面的模板。
-
在该
templates/hello
文件夹中,创建一个名为的新文件home.html
,然后开始键入djext
以查看该片段作为完成:选择完成时,将显示代码段的代码,并将光标放在代码段的插入点上:
-
在“标题”块的插入点,写入
Home
,在“内容”块的插入点,写入<p>Home page for the Visual Studio Code Django tutorial.</p>
,然后保存文件。这些行是扩展页面模板的唯一唯一部分: -
在
templates/hello
文件夹create中about.html
,使用代码片段插入样板标记,分别在About us
和<p>About page for the Visual Studio Code Django tutorial.</p>
的“ title”和“ content”块中插入,然后保存文件。 -
重复上一步以
templates/hello/contact.html
使用Contact us
和创建<p>Contact page for the Visual Studio Code Django tutorial.</p>
。 -
在应用程序的中
urls.py
,为/ about和/ contact页面添加路线。请注意,函数的name
参数path
定义{% url %}
了模板中标签中引用页面的名称。<span style="color:#333333"><code><span style="color:#000000">path(</span><span style="color:#a31515">"about/"</span><span style="color:#000000">, views.about, </span><span style="color:#001080">name</span><span style="color:#000000">=</span><span style="color:#a31515">"about"</span><span style="color:#000000">),</span> <span style="color:#000000">path(</span><span style="color:#a31515">"contact/"</span><span style="color:#000000">, views.contact, </span><span style="color:#001080">name</span><span style="color:#000000">=</span><span style="color:#a31515">"contact"</span><span style="color:#000000">),</span></code></span>
-
在中
views.py
,为/ about和/ contact路由添加引用各自页面模板的功能。还要修改home
功能以使用home.html
模板。<span style="color:#333333"><code><span style="color:#008000"># Replace the existing home function with the one below</span> <span style="color:#0000ff">def</span> <span style="color:#795e26">home</span><span style="color:#000000">(</span><span style="color:#001080">request</span><span style="color:#000000">):</span> <span style="color:#0000ff">return</span><span style="color:#000000"> render(request, </span><span style="color:#a31515">"hello/home.html"</span><span style="color:#000000">)</span> <span style="color:#0000ff">def</span> <span style="color:#795e26">about</span><span style="color:#000000">(</span><span style="color:#001080">request</span><span style="color:#000000">):</span> <span style="color:#0000ff">return</span><span style="color:#000000"> render(request, </span><span style="color:#a31515">"hello/about.html"</span><span style="color:#000000">)</span> <span style="color:#0000ff">def</span> <span style="color:#795e26">contact</span><span style="color:#000000">(</span><span style="color:#001080">request</span><span style="color:#000000">):</span> <span style="color:#0000ff">return</span><span style="color:#000000"> render(request, </span><span style="color:#a31515">"hello/contact.html"</span><span style="color:#000000">)</span></code></span>
运行应用程序#
放置所有页面模板后,保存views.py
,运行应用程序,然后打开浏览器进入主页以查看结果。在页面之间导航以验证页面模板是否正确扩展了基础模板。
与数据,数据模型和迁移工作#
许多网络应用程序都使用存储在数据库中的信息,而Django使使用model表示数据库中的对象变得容易。在Django中,模型是从派生的Python类,django.db.models.Model
代表一个特定的数据库对象,通常是一个表。您将这些类放置在应用程序的models.py
文件中。
使用Django,几乎可以完全通过代码中定义的模型来处理数据库。然后,随着模型的不断发展,Django的“迁移”会自动处理基础数据库的所有细节。常规工作流程如下:
- 对
models.py
文件中的模型进行更改。 - 运行
python manage.py makemigrations
以在migrations
文件夹中生成脚本,以将数据库从当前状态迁移到新状态。 - 运行
python manage.py migrate
以将脚本应用于实际数据库。
迁移脚本有效地记录了您随时间对数据模型所做的所有增量更改。通过应用迁移,Django会更新数据库以匹配您的模型。由于每个增量更改都有其自己的脚本,因此Django可以自动将数据库的任何先前版本(包括新数据库)迁移到当前版本。因此,您只需要关心中的模型,而不必关心models.py
基础数据库架构或迁移脚本。您让Django担当那部分!
同样,在代码中,您也只能使用模型类来存储和检索数据。Django处理基础细节。一个例外是您可以使用Django管理实用程序loaddata命令将数据写入数据库。该实用程序通常用于在migrate
命令初始化架构后初始化数据集。
使用db.sqlite3
文件时,您还可以使用SQLite浏览器之类的工具直接与数据库一起使用。使用此类工具在表中添加或删除记录是可以的,但是请避免对数据库架构进行更改,因为这样数据库将与您的应用程序模型不同步。相反,先更改模型,先运行makemigrations
,然后再运行migrate
。
数据库类型#
默认情况下,Django包含db.sqlite3
适用于开发工作的应用程序数据库文件。如何时使用SQLite(sqlite.org)所述,SQLite对于每天点击量少于100 K的中低流量站点工作正常,但不建议将其用于较大流量。它也仅限于单台计算机,因此不能在任何多服务器方案中使用,例如负载平衡和地理复制。
由于这些原因,请考虑使用生产级数据存储,例如PostgreSQL,MySQL和SQL Server。有关Django对其他数据库的支持的信息,请参阅数据库设置。您还可以使用适用于Python的Azure SDK来处理Azure存储服务,例如表和Blob。
定义模型#
Django模型还是从派生的Python类django.db.model.Models
,您将其放置在应用程序的models.py
文件中。在数据库中,每个模型都会自动获得一个名为的唯一ID字段id
。所有其他字段被定义为使用类型的数据从类的属性django.db.models
,如CharField
(不限文本), TextField
(无限文本), ,EmailField
,URLField
,IntegerField
,。DecimalField
,和等等。(有关详细信息,请参见Django文档中的Model字段参考。)BooleanField
DateTimeField
ForeignKey
ManyToMany
每个字段都具有一些属性,例如max_length
。该blank=True
属性表示该字段是可选的;null=true
表示值是可选的。还有一个choices
属性,用于将值限制为数据值/显示值元组数组中的值。
例如,添加以下类models.py
以定义一个数据模型,该数据模型表示简单消息日志中的带日期的条目:
<span style="color:#333333"><code><span style="color:#0000ff">from</span><span style="color:#000000"> django.db </span><span style="color:#0000ff">import</span><span style="color:#000000"> models</span>
<span style="color:#0000ff">from</span><span style="color:#000000"> django.utils </span><span style="color:#0000ff">import</span><span style="color:#000000"> timezone</span>
<span style="color:#0000ff">class</span> <span style="color:#267f99">LogMessage</span><span style="color:#000000">(</span><span style="color:#267f99">models</span><span style="color:#000000">.</span><span style="color:#267f99">Model</span><span style="color:#000000">):</span>
<span style="color:#000000"> message = models.CharField(</span><span style="color:#001080">max_length</span><span style="color:#000000">=</span><span style="color:#098658">300</span><span style="color:#000000">)</span>
<span style="color:#000000"> log_date = models.DateTimeField(</span><span style="color:#a31515">"date logged"</span><span style="color:#000000">)</span>
<span style="color:#0000ff">def</span> <span style="color:#795e26">__str__</span><span style="color:#000000">(</span><span style="color:#001080">self</span><span style="color:#000000">):</span>
<span style="color:#a31515">"""Returns a string representation of a message."""</span>
<span style="color:#000000"> date = timezone.localtime(</span><span style="color:#0000ff">self</span><span style="color:#000000">.log_date)</span>
<span style="color:#0000ff">return</span><span style="color:#000000"> f</span><span style="color:#a31515">"'</span><span style="color:#0000ff">{self.message}</span><span style="color:#a31515">' logged on {date.strftime('%A, </span><span style="color:#0000ff">%d</span><span style="color:#a31515"> %B, %Y at </span><span style="color:#0000ff">%X</span><span style="color:#a31515">')}"</span></code></span>
模型类可以包括返回从其他类属性计算出的值的方法。模型通常包括一个__str__
返回实例的字符串表示形式的方法。
迁移数据库#
由于您是通过编辑来更改数据模型的models.py
,因此您需要更新数据库本身。在VS Code中,在激活了虚拟环境的情况下打开一个终端(使用Terminal:Create New Integrated Terminal命令,Ctrl + Shift +`),导航到项目文件夹,然后运行以下命令:
<span style="color:#333333"><code><span style="color:#000000">python manage.py makemigrations</span>
<span style="color:#000000">python manage.py migrate</span></code></span>
在migrations
文件夹中查看以查看makemigrations
生成的脚本。您还可以查看数据库本身以查看架构是否已更新。
如果在运行命令时看到错误,请确保您没有使用先前步骤遗留下来的调试终端,因为它们可能没有激活虚拟环境。
通过模型使用的数据库#
放置好模型并迁移数据库后,您可以仅使用模型来存储和检索数据。在本节中,您将一个表单页面添加到应用程序中,通过该页面您可以记录消息。然后,您可以修改主页以显示这些消息。因为您在此处修改了许多代码文件,所以请注意细节。
-
在
hello
文件夹(您有views.py
)中,创建一个新文件forms.py
,该文件使用以下代码命名,该文件定义了一个Django表单,其中包含从数据模型绘制的字段LogMessage
:<span style="color:#333333"><code><span style="color:#0000ff">from</span><span style="color:#000000"> django </span><span style="color:#0000ff">import</span><span style="color:#000000"> forms</span> <span style="color:#0000ff">from</span><span style="color:#000000"> hello.models </span><span style="color:#0000ff">import</span><span style="color:#000000"> LogMessage</span> <span style="color:#0000ff">class</span> <span style="color:#267f99">LogMessageForm</span><span style="color:#000000">(</span><span style="color:#267f99">forms</span><span style="color:#000000">.</span><span style="color:#267f99">ModelForm</span><span style="color:#000000">):</span> <span style="color:#0000ff">class</span> <span style="color:#267f99">Meta</span><span style="color:#000000">:</span> <span style="color:#000000"> model = LogMessage</span> <span style="color:#000000"> fields = (</span><span style="color:#a31515">"message"</span><span style="color:#000000">,) </span><span style="color:#008000"># </span><span style="color:#0000ff">NOTE</span><span style="color:#008000">: the trailing comma is required</span></code></span>
-
在该
templates/hello
文件夹中,创建一个log_message.html
具有以下内容的新模板,该模板假定为该模板提供了一个名为的变量,form
用于定义表单主体。然后添加带有标签“ Log”的提交按钮。<span style="color:#333333"><code><span style="color:#000000">{% extends "hello/layout.html" %}</span> <span style="color:#000000">{% block title %}</span> <span style="color:#000000"> Log a message</span> <span style="color:#000000">{% endblock %}</span> <span style="color:#000000">{% block content %}</span> <span style="color:#800000"><form</span> <span style="color:#ff0000">method</span><span style="color:#000000">=</span><span style="color:#0000ff">"POST"</span> <span style="color:#ff0000">class</span><span style="color:#000000">=</span><span style="color:#0000ff">"log-form"</span><span style="color:#800000">></span> <span style="color:#000000"> {% csrf_token %}</span> <span style="color:#000000"> {{ form.as_p }}</span> <span style="color:#800000"><button</span> <span style="color:#ff0000">type</span><span style="color:#000000">=</span><span style="color:#0000ff">"submit"</span> <span style="color:#ff0000">class</span><span style="color:#000000">=</span><span style="color:#0000ff">"save btn btn-default"</span><span style="color:#800000">></span><span style="color:#000000">Log</span><span style="color:#800000"></button></span> <span style="color:#800000"></form></span> <span style="color:#000000">{% endblock %}</span></code></span>
注意:Django的
{% csrf_token %}
标签提供了跨站点请求伪造的保护。有关详细信息,请参见Django文档中的“跨站点请求伪造”保护。 -
在应用程序的
static/hello/site.css
文件中,添加一条规则以使输入表单更宽:<span style="color:#333333"><code><span style="color:#800000">input</span><span style="color:#000000">[</span><span style="color:#ff0000">name</span><span style="color:#000000">=</span><span style="color:#a31515">message</span><span style="color:#000000">] {</span> <span style="color:#ff0000">width</span><span style="color:#000000">: </span><span style="color:#098658">80%</span><span style="color:#000000">;</span> <span style="color:#000000">}</span></code></span>
-
在应用程序的
urls.py
文件中,为新页面添加一条路线:<span style="color:#333333"><code><span style="color:#000000">path(</span><span style="color:#a31515">"log/"</span><span style="color:#000000">, views.log_message, </span><span style="color:#001080">name</span><span style="color:#000000">=</span><span style="color:#a31515">"log"</span><span style="color:#000000">),</span></code></span>
-
在中
views.py
,定义命名的视图log_message
(由URL路由引用)。此视图处理HTTP GET和POST情况。在GET情况(本else:
节)中,它仅显示您在先前步骤中定义的表单。在POST的情况下,它将数据从表单中检索到数据对象(message
)中,设置时间戳记,然后将其保存到写入数据库的位置:<span style="color:#333333"><code><span style="color:#008000"># Add these to existing imports at the top of the file:</span> <span style="color:#0000ff">from</span><span style="color:#000000"> django.shortcuts </span><span style="color:#0000ff">import</span><span style="color:#000000"> redirect</span> <span style="color:#0000ff">from</span><span style="color:#000000"> hello.forms </span><span style="color:#0000ff">import</span><span style="color:#000000"> LogMessageForm</span> <span style="color:#0000ff">from</span><span style="color:#000000"> hello.models </span><span style="color:#0000ff">import</span><span style="color:#000000"> LogMessage</span> <span style="color:#008000"># Add this code elsewhere in the file:</span> <span style="color:#0000ff">def</span> <span style="color:#795e26">log_message</span><span style="color:#000000">(</span><span style="color:#001080">request</span><span style="color:#000000">):</span> <span style="color:#000000"> form = LogMessageForm(request.POST </span><span style="color:#0000ff">or</span> <span style="color:#0000ff">None</span><span style="color:#000000">)</span> <span style="color:#0000ff">if</span><span style="color:#000000"> request.method == </span><span style="color:#a31515">"POST"</span><span style="color:#000000">:</span> <span style="color:#0000ff">if</span><span style="color:#000000"> form.is_valid():</span> <span style="color:#000000"> message = form.save(</span><span style="color:#001080">commit</span><span style="color:#000000">=</span><span style="color:#0000ff">False</span><span style="color:#000000">)</span> <span style="color:#000000"> message.log_date = datetime.now()</span> <span style="color:#000000"> message.save()</span> <span style="color:#0000ff">return</span><span style="color:#000000"> redirect(</span><span style="color:#a31515">"home"</span><span style="color:#000000">)</span> <span style="color:#0000ff">else</span><span style="color:#000000">:</span> <span style="color:#0000ff">return</span><span style="color:#000000"> render(request, </span><span style="color:#a31515">"hello/log_message.html"</span><span style="color:#000000">, {</span><span style="color:#a31515">"form"</span><span style="color:#000000">: form})</span></code></span>
-
在您准备好尝试所有步骤之前,还需要执行一步!在中
templates/hello/layout.html
,在“ navbar” div中为消息记录页面添加一个链接:<span style="color:#333333"><code><span style="color:#008000"><!-- Insert below the link to Home --></span> <span style="color:#800000"><a</span> <span style="color:#ff0000">href</span><span style="color:#000000">=</span><span style="color:#0000ff">"{% url 'log' %}"</span> <span style="color:#ff0000">class</span><span style="color:#000000">=</span><span style="color:#0000ff">"navbar-item"</span><span style="color:#800000">></span><span style="color:#000000">Log Message</span><span style="color:#800000"></a></span></code></span>
-
运行该应用程序,然后打开浏览器到主页。选择导航栏上的“日志消息”链接,该链接将显示消息日志记录页面:
-
输入一条消息,选择Log,您应该回到主页。主页尚未显示任何已记录的消息(您稍后将对其进行补救)。也可以随时记录其他一些消息。如果需要,可以使用SQLite Browser之类的工具浏览数据库,以查看已创建记录。以只读方式打开数据库,否则请记住在使用该应用程序之前关闭数据库,否则该应用程序将因为数据库已锁定而失败。
-
完成后,停止应用程序。
-
现在,修改主页以显示记录的消息。首先,将应用
templates/hello/home.html
文件的内容替换为下面的标记。该模板需要一个名为的上下文变量message_list
。如果收到一个消息(已使用{% if message_list %}
标记选中),则它将遍历该列表({% for message in message_list %}
标记)以为每个消息生成表行。否则,该页面指示尚未记录任何消息。<span style="color:#333333"><code><span style="color:#000000">{% extends "hello/layout.html" %}</span> <span style="color:#000000">{% block title %}</span> <span style="color:#000000"> Home</span> <span style="color:#000000">{% endblock %}</span> <span style="color:#000000">{% block content %}</span> <span style="color:#800000"><h2></span><span style="color:#000000">Logged messages</span><span style="color:#800000"></h2></span> <span style="color:#000000"> {% if message_list %}</span> <span style="color:#800000"><table</span> <span style="color:#ff0000">class</span><span style="color:#000000">=</span><span style="color:#0000ff">"message_list"</span><span style="color:#800000">></span> <span style="color:#800000"><thead></span> <span style="color:#800000"><tr></span> <span style="color:#800000"><th></span><span style="color:#000000">Date</span><span style="color:#800000"></th></span> <span style="color:#800000"><th></span><span style="color:#000000">Time</span><span style="color:#800000"></th></span> <span style="color:#800000"><th></span><span style="color:#000000">Message</span><span style="color:#800000"></th></span> <span style="color:#800000"></tr></span> <span style="color:#800000"></thead></span> <span style="color:#800000"><tbody></span> <span style="color:#000000"> {% for message in message_list %}</span> <span style="color:#800000"><tr></span> <span style="color:#800000"><td></span><span style="color:#000000">{{ message.log_date | date:'d M Y' }}</span><span style="color:#800000"></td></span> <span style="color:#800000"><td></span><span style="color:#000000">{{ message.log_date | time:'H:i:s' }}</span><span style="color:#800000"></td></span> <span style="color:#800000"><td></span> <span style="color:#000000"> {{ message.message }}</span> <span style="color:#800000"></td></span> <span style="color:#800000"></tr></span> <span style="color:#000000"> {% endfor %}</span> <span style="color:#800000"></tbody></span> <span style="color:#800000"></table></span> <span style="color:#000000"> {% else %}</span> <span style="color:#800000"><p></span><span style="color:#000000">No messages have been logged. Use the </span><span style="color:#800000"><a</span> <span style="color:#ff0000">href</span><span style="color:#000000">=</span><span style="color:#0000ff">"{% url 'log' %}"</span><span style="color:#800000">></span><span style="color:#000000">Log Message form</span><span style="color:#800000"></a></span><span style="color:#000000">.</span><span style="color:#800000"></p></span> <span style="color:#000000"> {% endif %}</span> <span style="color:#000000">{% endblock %}</span></code></span>
-
在中
static/hello/site.css
,添加一条规则以稍微格式化表格:<span style="color:#333333"><code><span style="color:#800000">.message_list</span> <span style="color:#800000">th</span><span style="color:#000000">,</span><span style="color:#800000">td</span><span style="color:#000000"> {</span> <span style="color:#ff0000">text-align</span><span style="color:#000000">: </span><span style="color:#0451a5">left</span><span style="color:#000000">;</span> <span style="color:#ff0000">padding-right</span><span style="color:#000000">: </span><span style="color:#098658">15px</span><span style="color:#000000">;</span> <span style="color:#000000">}</span></code></span>
-
在中
views.py
,导入Django的通用ListView
类,我们将使用它来实现主页:<span style="color:#333333"><code><span style="color:#0000ff">from</span><span style="color:#000000"> django.views.generic </span><span style="color:#0000ff">import</span><span style="color:#000000"> ListView</span></code></span>
-
同样在中
views.py
,home
用一个名为的类(HomeListView
从派生)替换该函数,该类将ListView
自身与LogMessage
模型绑定并实现一个函数get_context_data
以生成模板的上下文。<span style="color:#333333"><code><span style="color:#008000"># Remove the old home function if you want; it's no longer used</span> <span style="color:#0000ff">class</span> <span style="color:#267f99">HomeListView</span><span style="color:#000000">(</span><span style="color:#267f99">ListView</span><span style="color:#000000">):</span> <span style="color:#a31515">"""Renders the home page, with a list of all messages."""</span> <span style="color:#000000"> model = LogMessage</span> <span style="color:#0000ff">def</span> <span style="color:#795e26">get_context_data</span><span style="color:#000000">(</span><span style="color:#001080">self</span><span style="color:#000000">, **</span><span style="color:#001080">kwargs</span><span style="color:#000000">):</span> <span style="color:#000000"> context = </span><span style="color:#267f99">super</span><span style="color:#000000">(HomeListView, </span><span style="color:#0000ff">self</span><span style="color:#000000">).get_context_data(**kwargs)</span> <span style="color:#0000ff">return</span><span style="color:#000000"> context</span></code></span>
-
在应用程序的中
urls.py
,导入数据模型:<span style="color:#333333"><code><span style="color:#0000ff">from</span><span style="color:#000000"> hello.models </span><span style="color:#0000ff">import</span><span style="color:#000000"> LogMessage</span></code></span>
-
同样在中
urls.py
,为新视图创建一个变量,该变量以LogMessage
降序检索五个最近的对象(这意味着它查询数据库),然后在模板上下文(message_list
)中为数据提供名称,并将模板标识为使用:<span style="color:#333333"><code><span style="color:#000000">home_list_view = views.HomeListView.as_view(</span> <span style="color:#001080">queryset</span><span style="color:#000000">=LogMessage.objects.order_by(</span><span style="color:#a31515">"-log_date"</span><span style="color:#000000">)[:</span><span style="color:#098658">5</span><span style="color:#000000">], </span><span style="color:#008000"># :5 limits the results to the five most recent</span> <span style="color:#001080">context_object_name</span><span style="color:#000000">=</span><span style="color:#a31515">"message_list"</span><span style="color:#000000">,</span> <span style="color:#001080">template_name</span><span style="color:#000000">=</span><span style="color:#a31515">"hello/home.html"</span><span style="color:#000000">,</span> <span style="color:#000000">)</span></code></span>
-
在中
urls.py
,修改主页的路径以使用home_list_view
变量:<span style="color:#333333"><code> <span style="color:#008000"># Replace the existing path for ""</span> <span style="color:#000000"> path(</span><span style="color:#a31515">""</span><span style="color:#000000">, home_list_view, </span><span style="color:#001080">name</span><span style="color:#000000">=</span><span style="color:#a31515">"home"</span><span style="color:#000000">),</span></code></span>
-
启动应用程序,然后打开浏览器到主页,该页面现在应该显示消息:
-
完成后,停止应用程序。
使用与页面模板调试#
正如上一节所示,页面模板可以包含程序指令像{% for message in message_list %}
和{% if message_list %}
,而不是只喜欢被动,声明元素{% url %}
和{% block %}
。结果,与其他任何过程代码一样,您可能在模板内部出现编程错误。
幸运的是,当您"django": true
处于调试配置中时(如已执行),Python VS Code扩展提供了模板调试。以下步骤演示了此功能:
-
在中
templates/hello/home.html
,在{% if message_list %}
和{% for message in message_list %}
行上都设置断点,如下图的黄色箭头所示: -
在调试器中运行该应用程序,然后打开浏览器到主页。(如果您已经在运行调试器,则不必在设置断点后重新启动应用程序;只需刷新页面即可。)观察到VS Code进入了
{% if %}
语句模板中的调试器,并在其中显示了所有上下文变量。该变量窗格: -
使用“跳过(F10)”命令单步执行模板代码。观察到调试器会遍历所有声明性语句,并在任何过程代码处暂停。例如,单步执行
{% for message in message_list %}
循环可让您检查中的每个值,message
并步进至<td>{{ message.log_date | date:'d M Y' }}</td>
。 -
您也可以在“调试控制台”面板中使用变量。(
date
但是,控制台中目前不提供Django过滤器,如。) -
准备就绪后,选择继续(F5)以完成应用程序的运行并在浏览器中查看渲染的页面。完成后,停止调试器。
可选的活动#
以下各节介绍了在使用Python和Visual Studio Code时可能会有所帮助的其他步骤。
为环境创建一个requirements.txt文件#
通过源代码控制或其他方式共享应用程序代码时,在虚拟环境中复制所有文件是没有意义的,因为收件人始终可以自己重新创建该环境。
因此,开发人员通常会从源代码管理中省略虚拟环境文件夹,而使用requirements.txt
文件描述应用程序的依赖项。
尽管可以手动创建文件,但也可以使用以下pip freeze
命令根据已激活的环境中安装的确切库来生成文件:
-
使用Python:Select Interpreter命令选择选定的环境后,运行Terminal:Create New Integrated Terminal命令(Ctrl + Shift +`)以打开一个激活了该环境的终端。
-
在终端中,运行
pip freeze > requirements.txt
以requirements.txt
在项目文件夹中创建文件。
收到项目副本的任何人(或任何构建服务器)都只需运行pip install -r requirements.txt
命令即可在活动环境中重新安装应用程序所依赖的软件包。
注意:
pip freeze
列出当前环境中已安装的所有Python软件包,包括当前未使用的软件包。该命令还会列出具有确切版本号的软件包,您可能希望将其转换为范围,以在将来获得更大的灵活性。有关更多信息,请参见pip命令文档中的需求文件。
创建一个超级用户并启用管理界面#
默认情况下,Django为受身份验证保护的Web应用程序提供管理界面。该界面通过内置django.contrib.admin
应用实现,默认情况下包含在项目INSTALLED_APPS
列表(settings.py
)中,而身份验证则通过内置django.contrib.auth
应用处理,INSTALLED_APPS
默认情况下也处于内置状态。
执行以下步骤以启用管理界面:
-
在您的虚拟环境中打开VS Code中的终端,然后运行命令
python manage.py createsuperuser --username=<username> --email=<email>
,当然用您的个人信息替换<username>
和<email>
,在应用程序中创建超级用户帐户。运行命令时,Django会提示您输入并确认密码。请务必记住您的用户名和密码组合。这些是您用来验证应用程序的凭据。
-
在项目级别
urls.py
(web_project/urls.py
在本教程中)中添加以下URL路由,以指向内置的管理界面:<span style="color:#333333"><code><span style="color:#008000"># This path is included by default when creating the app</span> <span style="color:#000000"> path(</span><span style="color:#a31515">"admin/"</span><span style="color:#000000">, admin.site.urls),</span></code></span>
-
运行服务器,然后打开浏览器到应用程序的/ admin页面(例如,
http://127.0.0.1:8000/admin
使用开发服务器时)。 -
出现登录页面,礼貌为
django.contrib.auth
。输入您的超级用户凭据。 -
通过身份验证后,您会看到默认的管理页面,通过该页面可以管理用户和组:
您可以根据需要自定义管理界面。例如,您可以提供编辑和删除数据库中条目的功能。有关进行自定义的更多信息,请参阅Django管理站点文档。
使用泊坞扩展Django应用程序创建一个容器#
该泊坞窗扩展可以很容易地构建,管理和部署应用程序集装箱从Visual Studio代码。如果您有兴趣学习如何为本教程中开发的Django应用创建Python容器,请查看容器教程中的Python,它将逐步指导您:
- 创建一个
Dockerfile
描述简单Python容器的文件。 - 生成,运行和验证Django应用程序的功能。
- 调试在容器中运行的应用程序。
接下来的步骤#
祝贺您完成在Visual Studio Code中使用Django的演练!
可以在GitHub上找到本教程中完整的代码项目:python-sample-vscode-django-tutorial。
在本教程中,我们仅介绍了Django可以做的所有事情。请确保访问Django文档和Django官方教程,以获取有关视图,模板,数据模型,URL路由,管理界面,使用其他类型的数据库,部署到生产等的更多详细信息。
若要在生产网站上尝试您的应用程序,请查看教程“使用Docker容器将Python应用程序部署到Azure App Service”。Azure还提供了一个标准容器,即Linux上的App Service,您可以从VS Code中向其中部署Web应用程序。