Python实战之Web开发
创建Django项目
我使用Pycharm来创建Django项目,也可以自己手动创建虚拟环境等,配置如下,所有代码可点击这里查看
运行,在浏览器输入http://localhost:8000/,显示如下表明项目创建正确
创建应用程序
终端输入python manage.py migrate
创建数据库,用于将项目相关的信息存储,然后输入python manage.py startapp learning_log
来创建应用程序,项目结构如下
.venv/
- Python 虚拟环境目录。
- 包含你项目安装的所有依赖(如 Django)。
- 通常会在
.gitignore
中忽略它。
manage.py
管理工具脚本,用于执行各种 Django 命令,如:
1
2
3
4python manage.py runserver # 启动开发服务器
python manage.py makemigrations # 创建迁移
python manage.py migrate # 应用迁移到数据库
python manage.py createsuperuser # 创建管理员账户
__init__.py
- 让该目录成为 Python 包可为空
settings.py
- Django 项目的配置文件
- 包含数据库设置、应用注册、模板路径、静态文件配置、安全设置等
urls.py
项目级URL 路由入口
将不同的 URL 请求分发给对应的 app 处理
通常写法:
1
2
3
4
5from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('learning_log.urls')), # 指向 app 的 url
]
wsgi.py
- 用于部署到 WSGI 服务器
- 生产环境使用
asgi.py
- 用于部署到 ASGI 服务器
- 用于支持 WebSocket、异步视图
__init__.py
- 表示这是一个 Python 包
admin.py
用于注册模型到 Django 管理后台(admin site)
示例:
1
2
3from django.contrib import admin
from .models import Entry
admin.site.register(Entry)
apps.py
- 定义 app 的元信息,通常不需修改
- 当你在
INSTALLED_APPS
中注册 app 时,这里也会用到
models.py
- 定义数据模型(Model)类
- 每个模型对应数据库中的一张表
views.py
- 视图函数,用来处理用户请求并返回响应
- 例如返回 HTML 页面、JSON 数据等
tests.py
- 单元测试文件,可编写自动化测试
- Django 内建测试框架基于 Python 的
unittest
migrations/
自动生成的数据库迁移文件
每当你修改模型(models.py)并运行:
1
python manage.py makemigrations
就会在此生成一个迁移脚本,用于记录数据库变更
templates/
- 存放 HTML 模板文件的目录
- 用于 Django 的模板引擎渲染页面
例如:
你可以在 templates/
中创建 index.html
,然后在视图中渲染:
1 | from django.shortcuts import render |
db.sqlite3
- 默认使用的 SQLite 数据库文件
- 存储了你项目所有模型的数据内容
文件/文件夹 | 作用说明 |
---|---|
.venv/ |
虚拟环境,包含依赖 |
manage.py |
管理命令脚本 |
DjangoProject/settings.py |
项目配置 |
DjangoProject/urls.py |
URL 路由入口 |
DjangoProject/wsgi.py |
部署用 WSGI 接口 |
learning_log/ |
自定义 app |
models.py |
定义数据库模型 |
views.py |
编写视图函数 |
admin.py |
注册后台模型 |
migrations/ |
数据库变更记录 |
templates/ |
HTML 模板目录 |
db.sqlite3 |
SQLite 数据库文件 |
应用设置
修改models.py文件如下
1 | from django.db import models |
在settings.py
的INSTALLED_APPS
中添加learning_log
,然后执行数据库迁移,如下
1 | python manage.py makemigrations |
创建超级用户
输入python manage.py createsuperuser
来创建管理者,账户名、密码、邮箱自行设置,其中密码会被隐藏
随后在admin.py文件中修改代码如下
1 | from django.contrib import admin |
这段代码用于向管理网站注册Topic
由于我在创建项目时没有勾选“启用Django admin”,因此这里需要对项目进行简单的更改
将urls.py中注释的部分取消
1
2
3
4
5
6# from django.contrib import admin
from django.urls import path
urlpatterns = [
# path('admin/', admin.site.urls),
]在settings.py的
INSTALLED_APPS
中添加django.contrib.admin
访问http://localhost:8000/admin/,显示如下
输入账户和密码,登录进去界面显示如下
User和Group是Django自动在管理网站添加的模型,而Topic是我们刚刚自己添加的。此时可以点击Topic,添加任意的主题
定义Entry
在models.py中添加如下代码
1 | class Entry(models.Model): |
这里主要说一下两个地方
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
是将每一条Entry
都关联一个 Topic,形成多对一的关系元信息配置(Meta):默认 Django 会把模型名称小写加 “s” 做复数,这句是为了告诉 Django这个模型的复数名称设置为
entries
,而不是默认的Entrys
由于修改了模型文件,因此我们需要再次迁移数据库,执行
1 | python manage.py makemigrations learning_log |
然后在管理网站注册Entry:admin.site.register(Entry)
(有关模型导入的问题这里不做叙述)
进入管理网站后会发现多出了一个Entries条目,进入该条目,点击下拉框就可以选择对应的主题,如下图
这时候我们就可以创建条目并将其与对应的主题相关联。不过,目前除了后台管理界面,我们还没任何可供用户访问的界面,下一步我们将尝试创建一个网页来让其他人访问
创建网页
使用Django创建网页主要分为三个步骤,定义URL、编写视图、编写模板,完成这三个部分的顺序通常无关紧要,每个人都可以按照个人喜好来实现
映射URL
当前http://localhost:8000返回默认的Django网站,下面进行修改,打开urls.py文件,在`urlpatterns`中添加`path(‘’, include(‘learning_log.urls’)),`表示我们导入应用learning_log中的url。然后在应用learning_log中添加urls.py文件,内容如下
1 | from django.urls import path |
这段代码主要为当前 app 即(learning_log)配置 URL 路由,其中app_name = 'learning_log'
,给这个 app 的 URL 配置一个命名空间,防止与其他 app 中的 URL 名称冲突,在模板中使用 {% url 'learning_log:index' %}
就能明确地调用这个 URL。urlpatterns
是 Django 查找 URL 的核心列表,每一个 path()
定义了一个 URL 与视图的映射。path('', views.index, name='index'),
第一个参数是一个字符串用于正确的路由请求,这里表示匹配根路径,第二个参数表示当匹配到 /
时,调用 views.py
中的 index()
函数,第三个参数给这个 URL 取了一个名字叫 'index'
,在模板中可以用 {% url 'learning_log:index' %}
来反向生成地址
编写视图
视图函数接受请求中的信息,准备好生成网页所需的数据,然后将其发送给浏览器。在前面我们调用了 views.py
中的 index()
函数,但该函数还未编写,打开views.py文件,添加代码如下
1 | from django.shortcuts import render |
它接受一个 request
对象作为参数,这是 Django 在用户访问网页时自动传入的请求信息对象。函数的返回值是 render(request, 'learning_log/index.html')
,表示让 Django 去找一个路径为 learning_log/index.html
的模板文件,并渲染它,默认的模板查找路径为app/templates/app_name/文件名.html
编写模板
模板定义网页的外观,每当访问网页时,Django都将填入相关的数据用于显示,我们的template文件夹位于根目录,所以无需在app目录中重新创建,但需要在settings.py的TEMPLATES
中检查是否存在'DIRS': [BASE_DIR / 'templates']
,以便正确检索html文件
在template文件夹中创建learning_log文件夹并在其中创建index.html,添加代码如下
1 | <p>Learning Log</p> |
这里添加了两个段落,运行访问界面如下
创建其他网页
创建父模板
在index.html所在的目录中,创建一个base.html文件,这个模板将包含所有页面的通用元素,并将所有子模板都继承它,添加内容如下
1 | <p> |
1 | <p> |
这段表示页面顶部的一个链接,点击后会跳转到名为 'learning_log:index'
的 URL 对应的页面。
{% url 'learning_log:index' %}
是 Django 模板语言提供的 URL 反向解析标签。'learning_log'
是在learning_log/urls.py
中定义的app_name
。'index'
是在urlpatterns
中为首页设置的name
。
所以最终这个标签会被渲染为:
1 | <a href="/">Learning Log</a> |
如果将 index
页面映射到 /
,那么这个链接就是返回首页的作用。
1 | {% block content %}{% endblock content %} |
这是 Django 模板语言中非常关键的部分,称为 模板块(template block),它用于定义“可扩展区域”。
解释如下:
{% block content %}` 是定义一个名为 `content` 的内容区块。 - `{% endblock content %}
表示这个区块的结束。
换句话说,子模板可以继承这个模板,并用自己的内容替换掉这个 block 区域,例如:
1 | {% extends "learning_log/base.html" %} |
创建子模板
重写index.html文件,使其继承base.html,如下
1 | {% extends 'learning_log/base.html' %} |
这里将index从base继承下来,使用{% block content %}`定义一个`content`并插入内容,使用`{% endblock content %}
结束content
块,里面内容将显示在界面上,此时通过修改父模板将修改所有继承它的界面,方便统一管理
显示所有主题的页面
首先定义URL,添加path('topics/', views.topics, name='topics')
,在视图中定义topics
函数如下
1 | def topics(request): |
将所有主题按照时间顺序排序并返回,然后创建topics.html,内容如下
1 | {% extends 'learning_log/base.html' %} |
这里主要将topics
中的内容通过无序列表的方式呈现出来。随后在base.html中添加连字符以及代码<a href="{% url 'learning_log:topics' %}">Topics</a>
,这将产生一个与Topics匹配的URL链接,访问http://localhost:8000/topics/,如下
显示特定主题
我们已经创建了两次页面,对其基本流程应该有所了解了,后续关于URL、视图、模板相关的内容将进行简略,我们再次创建一个页面用于显示特定的主题及其所有的条目
1 | # URL |
1 | {# 模板 #} |
在topic
函数中先通过id
获取到特定的主题,然后将主题中的条目降序排列,最后将Topic
和Entries
返回。模板主要把entries
按照特定的格式显示,“|”表示过滤符,也就是将时间按照:January 1, 2025 23:00格式。linebreaks
是将文本中的换行符转变为浏览器理解的内容。
然后修改topics.html,将每个主题都映射为对应的链接
1 | {% for topic in topics %} |
运行之后在Topic页面点击主题,显示如下