尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Django新手入门:跑通请求响应闭环,拥有第一个Web应用

Django新手入门:跑通请求响应闭环,拥有第一个Web应用 新手学 Django 最大的问题往往不是 Python 语法不熟而是打开教程之后不知道该看什么。ORM、中间件、Admin、表单、DRF、JWT、Celery……每一个词看起来都重要每一个词都能再展开一本书。收藏夹存了几十个链接但依然不知道第一行代码该写在哪个文件里。这篇文章尝试给出一条完全不同的路径学 Django不要先追概念先抓住一条主线。把这条主线跑通你就拥有一个真正能跑起来的 Web 应用。后续所有进阶内容本质上都是在扩展这条主线上的某个环节。这条主线就是用户在浏览器输入网址Django 收到请求后通过 URL 路由找到视图函数视图函数从数据库取出数据交给模板渲染成 HTML再返回给浏览器。听上去简单但很多新手恰恰是卡在“每个部分都会一点但串不起来”的状态。还有一个大家常问的问题Django 在国内使用广泛吗从招聘需求和开源项目来看它依然是 Python Web 生态中最常见的选择之一尤其是在快速交付、企业内部系统、内容管理和数据平台后台这些场景里Django 的出现频率非常高。所以不管你是准备找工作、写毕设还是给团队搭内部工具Django 都值得认真学一遍。1. 新手学 Django 最大的障碍不是语法而是没有主线很多人的学习路径是这样的先花两个月学 Python 基础然后开始看 Django 教程紧接着被一堆名词淹没。比如“中间件”一开始就牵扯到请求处理链“Django Admin”需要在模型定义好之后才有意义“DRF”要同时理解序列化、视图集和路由“Celery”又涉及消息队列和异步任务。这些概念单拿出来都不难但它们之间互相依赖新手如果一上来就试图全部理解很快就会失去耐心。这里真正容易踩坑的地方是你花大量时间去看了一个“看起来很重要”的知识点但它在你的项目里根本没有被用到。比如还没跑通一个页面就开始研究多重继承的类视图和信号量机制结果代码跑不起来概念也记不住。拿学车来类比新手第一步应该是先发动汽车、踩油门、走起来而不是先搞清楚发动机缸内直喷和涡轮增压的区别。Django 也一样你需要的不是“全面理解”而是“先跑通一个最小可用的闭环”。我建议的学习顺序是先把“请求 → 路由 → 视图 → 模型 → 模板 → 响应”这条链路跑通。再回过来慢慢补概念。每学一个新概念都把它挂到这条链路的某个环节上。这样你不会迷路因为你始终知道自己在整条链路里的位置。2. Django 到底是什么MTV 架构和 MVC 到底什么关系先从定义说起。Django 是一个基于 Python 的 Web 开发框架它的特点是“全家桶”式设计ORM、模板引擎、表单处理、认证系统、Admin 后台、中间件机制等通通内置。好处是你不用为了做一个网站到处拼第三方库坏处是新手容易在“应有尽有”里失去方向。理解 Django核心是理解它的 MTV 架构。很多人以前学过 MVCModel-View-Controller这两个概念容易混淆但其实对应关系很简单概念传统 MVCDjango 中的对应主要负责数据层Modelmodels.py定义数据结构操作数据库控制层Controllerviews.py接收请求处理业务逻辑展示层Viewtemplates 目录渲染 HTML 页面也就是说Django 中的 View 承担了传统 MVC 里 Controller 的职责而传统 MVC 中的 View展示页面在 Django 里对应的是 Template模板。这也是新手最容易困惑的一点很多人以为 Django 的 View 就是负责页面显示实际上它负责的是业务逻辑。举个生活中的例子Model 像仓库管理员负责记录和提供商品数据View 像餐厅后厨接到点菜单后决定做什么菜、怎么搭配业务逻辑Template 像摆盘服务员把做好的菜摆到盘子里端出去页面渲染。三者协同工作互不越界这就是 MTV 架构的核心思想。Django 的 ORM 则让你用 Python 类来描述数据库表不需要直接写 SQL。比如你在 models.py 里定义一个类Django 自动帮你生成对应的数据库表结构增删改查也通过对象方法完成这对新手非常友好。3. 主线地图浏览器请求到页面响应的完整旅程我们把这条主线拆成七步提前建立一个心智模型。这一步非常重要因为后面你写每一行代码时都会知道自己在整条链路里的位置。假设用户在浏览器里输入http://127.0.0.1:8000/blog/并回车Django 内部发生了这些事开发服务器接收到 HTTP 请求。请求先经过中间件此处先不用深究把它理解成“门口安检”。Django 根据请求的 URL去urls.py里找到对应的路由规则。路由规则把请求交给对应的视图函数也就是views.py里的一个函数或类。视图函数执行业务逻辑需要数据时通过 ORM 查询models.py中定义的模型。视图把查询结果打包成上下文交给模板系统模板用 HTML 渲染出最终页面。HTTP 响应返回浏览器用户看到页面。在这个闭环里你只需要重点理解四个文件urls.py决定谁来处理views.py决定怎么处理models.py定义数据长什么样templates目录决定页面长什么样。后面的所有章节都是围绕这个闭环展开的。中间件、表单、认证、DRF本质上都是在给这个闭环加环节或者改细节。你始终清楚自己在哪个环节就不会乱。4. 主线第一步环境准备与项目创建这一节我们从零开始搭建一个完整可运行的项目。4.1 安装 Python 与创建虚拟环境Django 是 Python 框架首先确保电脑上有 Python 环境。这里建议使用 Python 3.8 及以上版本较新的 Python 3.10、3.11 都能很好地支持当前主流 Django 版本。具体版本以你实际安装为准不要在版本号上纠结太久。验证 Python 是否安装成功python --version建议所有 Python 项目都使用虚拟环境。虚拟环境的作用是隔离不同项目的依赖避免项目 A 升级了某个库导致项目 B 无法运行。创建虚拟环境python -m venv venvWindows 系统激活虚拟环境venv\Scripts\activatemacOS 或 Linux 系统激活虚拟环境source venv/bin/activate激活成功后命令行前面会出现(venv)前缀这就代表你已经进入了虚拟环境。后面所有安装和运行命令都要在这个环境里执行。4.2 安装 Django 并创建项目在虚拟环境里安装 Djangopip install django python -m django --version第一条命令安装 Django第二条命令验证版本号。不同版本的 Django 在细节上有差异本文步骤以 Django 4.x/5.x 的常见用法为主线但即便你安装的是其他版本整体流程也是一样的。创建项目和应用django-admin startproject mysite cd mysite python manage.py startapp blog这里有两个概念需要区分清楚project整个网站的配置中心负责全局设置、路由入口和启动管理。app一个具体的业务模块。比如博客、评论、用户中心都可以拆成独立的 app。startproject mysite创建了整个项目startapp blog创建了博客应用。一个项目里可以有多个 app这也是 Django 组织业务模块的方式。4.3 看懂项目目录结构创建完成后目录结构大致如下mysite/ ├── manage.py ├── mysite/ │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ ├── asgi.py │ └── wsgi.py └── blog/ ├── __init__.py ├── admin.py ├── apps.py ├── migrations/ ├── models.py ├── tests.py └── views.py这里新手容易犯迷糊的地方是出现了两个mysite目录。外层mysite是项目根目录里层mysite是项目的配置包里面放着settings.py和urls.py。以后你改网站配置基本就是改内层mysite里的文件。4.4 启动默认页面先不写任何业务代码启动 Django 自带的开发服务器看一眼效果python manage.py runserver浏览器访问http://127.0.0.1:8000/如果看到 Django 的欢迎页说明你的环境已经完全打通了。这一步的校验意义在于你的 Python、Django、虚拟环境和项目创建命令都没有问题可以安心进入下一节。5. 主线第二步注册应用并创建第一张模型表项目能启动只是第一步接下来要让 Django 真正管理你的业务数据。5.1 在 settings.py 中注册应用打开mysite/settings.py找到INSTALLED_APPS列表把blog加进去# 文件路径mysite/settings.py INSTALLED_APPS [ django.contrib.admin, django.contrib.auth, django.contrib.contenttypes, django.contrib.sessions, django.contrib.messages, django.contrib.staticfiles, blog, ]注册 app 是新手最容易遗漏的步骤。如果你创建了 app 却不在这里注册Django 不会知道它的存在后面执行迁移时会提示找不到相关的迁移记录。5.2 了解默认数据库配置同样在settings.py里往下找会看到DATABASES配置。默认情况下Django 使用的是 SQLite 数据库# 文件路径mysite/settings.py DATABASES { default: { ENGINE: django.db.backends.sqlite3, NAME: BASE_DIR / db.sqlite3, } }SQLite 是一个文件型数据库对新手非常友好不需要安装数据库服务不需要配置账号密码数据保存在一个.sqlite3文件里。等以后项目上线或数据量变大再切换成 PostgreSQL 或 MySQL 即可。5.3 编写第一个模型模型是 MTV 架构里的 M它决定了数据表长什么样。打开blog/models.py定义一个博客文章模型# 文件路径blog/models.py from django.db import models class Post(models.Model): title models.CharField(max_length200) content models.TextField() created_at models.DateTimeField(auto_now_addTrue) def __str__(self): return self.title这里每个字段都对应数据库表中的一列CharField对应数据库里的变长字符串max_length200限制最大长度。TextField对应长文本适合存放文章正文。DateTimeField对应日期时间auto_now_addTrue表示创建记录时自动填入当前时间。__str__方法不是必须的但强烈建议加上。它决定了这条记录在 Django Admin 后台和 shell 里显示成什么样子直接返回标题比返回Post object (1)直观得多。5.4 生成并执行迁移模型写好后需要让 Django 根据模型生成数据库表。这里有两个命令python manage.py makemigrations blog python manage.py migrate第一个命令makemigrations会根据模型的变化生成迁移文件相当于“创建数据库建表脚本”第二个命令migrate真正执行迁移把表结构写入数据库。执行migrate时Django 不仅会创建blog_post表还会初始化内置的认证、会话等系统表所以输出会包含很多OK。看到类似下面的信息就说明成功了Operations to perform: Apply all migrations: admin, auth, blog, contenttypes, sessions Running migrations: Applying blog.0001_initial... OK到这里你的数据库已经有一张blog_post表了。你全程没有写一句 SQL这就是 ORM 的威力。6. 主线第三步URL 路由和 View 视图把数据取出来模型建好了接下来要让用户在浏览器里能看到这些数据。这一步打通“URL → 视图”的链路。6.1 创建 app 内的 urls.py在blog目录下新建一个文件urls.py专门管理博客应用的内部路由# 文件路径blog/urls.py from django.urls import path from . import views app_name blog urlpatterns [ path(, views.post_list, namepost_list), ]path(, ...)的意思是访问http://127.0.0.1:8000/blog/时把请求交给views.post_list这个视图函数处理。app_name blog用于命名空间避免多个 app 之间的路由重名。6.2 在项目 urls.py 中注册回到项目配置目录下的mysite/urls.py把blog的路由挂载到项目上# 文件路径mysite/urls.py from django.contrib import admin from django.urls import path, include urlpatterns [ path(admin/, admin.site.urls), path(blog/, include(blog.urls)), ]include的作用是把blog应用的所有路由整体挂到/blog/前缀下。以后blog/urls.py里新增任何路由都会自动带上/blog/前缀。6.3 写第一个视图函数打开blog/views.py先写一个最简单的视图# 文件路径blog/views.py from django.http import HttpResponse def post_list(request): return HttpResponse(这里是博客文章列表)保存后刷新浏览器访问http://127.0.0.1:8000/blog/应该能看到“这里是博客文章列表”这句话。这一步虽然简单却是一个完整的请求响应闭环URL 路由匹配到了视图视图返回了响应。6.4 通过 shell 插入测试数据接下来往数据库里放几条数据方便后面测试页面展示。python manage.py shell在交互式命令行里执行from blog.models import Post Post.objects.create(title第一篇文章, content你好Django 主线教程) Post.objects.create(title第二篇文章, content这里是从数据库读取的内容) Post.objects.all()Post.objects.all()会返回所有文章记录。看到两个Post对象说明数据已经成功写入数据库。如果你想删除某条数据可以用Post.objects.get(id1).delete()或者用Post.objects.filter(id1).delete()批量删除这些都属于 ORM 的日常操作。现在把视图函数升级一下让它从数据库里把文章取出来# 文件路径blog/views.py from django.http import HttpResponse from .models import Post def post_list(request): posts Post.objects.all().order_by(-created_at) result for post in posts: result f{post.title} - {post.created_at}\n return HttpResponse(result)这段代码用order_by(-created_at)按创建时间倒序排列然后手动拼接字符串返回。这种方式虽然能显示数据但很不优雅。真正专业的做法是交给模板渲染这正是下一节的内容。7. 主线第四步模板渲染完整页面模板是 MTV 架构里的 T负责把数据渲染成漂亮的 HTML 页面。7.1 创建模板目录Django 寻找模板时会默认在每个已注册的 app 下查找templates目录。所以我们按照约定在blog目录下创建templates/blog/两层目录然后新建post_list.html文件。之所以多包一层blog是为了防止多个 app 之间出现同名模板文件时产生冲突。这是一个良好的工程习惯。7.2 编写模板文件打开blog/templates/blog/post_list.html写入以下内容!-- 文件路径blog/templates/blog/post_list.html -- !DOCTYPE html html langzh-CN head meta charsetUTF-8 title博客文章列表/title /head body h1博客文章列表/h1 ul {% for post in posts %} li h2{{ post.title }}/h2 p{{ post.content }}/p small{{ post.created_at }}/small /li {% empty %} li还没有文章/li {% endfor %} /ul /body /html模板语法需要在脑内建立一个映射{% for post in posts %}是 Django 模板的循环标签等价于 Python 里的for循环。{{ post.title }}是模板变量会输出该字段的实际值。{% empty %}在列表为空时显示替代内容。模板语法掌握这三个元素就能应付大部分场景{{ }}输出变量{% %}执行逻辑{# #}写注释。7.3 修改视图使用 render把视图改成渲染模板的方式# 文件路径blog/views.py from django.shortcuts import render from .models import Post def post_list(request): posts Post.objects.all().order_by(-created_at) return render(request, blog/post_list.html, {posts: posts})render函数接收三个参数request请求对象模板路径这里的blog/post_list.html相对于templates目录上下文一个字典模板里可以直接使用字典的 key 作为变量名。之前手动拼接字符串的做法有一个隐患如果文章内容里包含 HTML 标签Django 默认会进行转义这其实是安全设计防止 XSS 注入。模板渲染的语义更清晰也把业务逻辑和页面展示彻底分开了。7.4 验证完整闭环保存所有文件再次访问http://127.0.0.1:8000/blog/。如果你在第 6 节通过 shell 创建了两篇文章现在页面应该以 HTML 列表的形式展示出这两篇文章的标题、内容和发布时间。到这里你已经完整跑通了主线浏览器发请求路由匹配视图视图查询数据库数据库结果交给模板模板渲染成 HTML 返回浏览器。这是一个完整的 Web 应用不是“Hello World”而是真正包含数据库读写的项目。8. 运行验证与效果确认为了确认你没有在之前的步骤里遗漏什么这里把完整的启动和验证流程汇总一下。进入项目根目录包含manage.py的目录确保虚拟环境已激活然后执行python manage.py runserver浏览器访问http://127.0.0.1:8000/blog/。判断成功的标准有三个页面顶部显示“博客文章列表”页面上能看到你通过 shell 插入的两篇文章文章按创建时间倒序排列最新的一篇在最上面。如果缺少某一条优先按下面的顺序排查先看终端里runserver的日志有没有红色报错信息再看浏览器地址栏的 URL 是不是http://127.0.0.1:8000/blog/不要漏掉/blog/前缀最后确认blog/urls.py里的视图函数名和blog/views.py里的函数名是否一致。如果你希望页面刷新后能看到变化可以多插入几条数据再刷新python manage.py shellfrom blog.models import Post Post.objects.create(title第三条, content再刷新一下页面试试) for post in Post.objects.all(): print(post.id, post.title, post.created_at)不要小看这种验证步骤。很多新手项目跑不通不是代码写错而是没有建立起“预期输出”的概念。你一旦知道“正确结果长什么样”排错效率会高很多。9. 常见问题与排查思路新手在跑这条主线时大概率会遇到以下几个问题。这里整理成一张排查表建议收藏备用。问题现象可能原因排查方式解决方案执行django-admin找不到命令虚拟环境未激活或 Django 未安装查看命令行是否有(venv)前缀执行pip list查看 Django 是否存在激活虚拟环境重新执行pip install django提示ModuleNotFoundError: No module named djangoPython 运行时不在虚拟环境里执行which python查看 Python 路径确认已激活虚拟环境换用python -m pip install django安装runserver启动后访问页面显示 404URL 路径不匹配或未注册路由检查mysite/urls.py里的include是否正确检查blog/urls.py是否存在修改路由配置注意是否缺少/blog/前缀提示TemplateDoesNotExist模板目录位置不对或未按templates/blog/约定创建查看 app 目录下是否有完整的templates/blog/post_list.html路径按约定创建模板目录确认文件后缀是.html而不是.txt执行migrate时提示表已存在或迁移冲突之前执行过部分迁移或模型被手动改过查看blog/migrations目录下的迁移文件状态确保模型定义好后先makemigrations再migrate必要时在测试环境重置数据库页面数据显示为纯文本或转义后的 HTML模板里没有遍历posts而是直接输出了变量检查模板里是否写了{% for post in posts %}使用{% for %}标签遍历列表不要直接{{ posts }}修改了models.py但页面数据没变化只改了代码没有执行迁移命令执行python manage.py makemigrations和python manage.py migrate模型字段变更后必须重新生成迁移并执行runserver提示端口被占用上一个开发服务器进程未关闭查看终端日志中的报错信息关闭占用进程或使用python manage.py runserver 8001换一个端口其中端口占用和虚拟环境未激活是两个出现频率最高的问题。如果你用的是一体化 IDE比如 PyCharm 或 VS Code它们可能默认使用全局 Python 环境这也会导致明明安装过 Django 却报找不到模块。10. 最佳实践与后续学习方向主线跑通之后你已经具备了继续深入的基础。接下来往哪个方向走我给出一个明确的学习路线按顺序推进不要跳。第一步学 Django Admin。你只需要把blog/models.py里的Post注册到blog/admin.py就能在后台可视化地增删改查文章不用自己写管理页面。# 文件路径blog/admin.py from django.contrib import admin from .models import Post admin.register(Post) class PostAdmin(admin.ModelAdmin): list_display (title, created_at)访问http://127.0.0.1:8000/admin/用createsuperuser创建管理员账号后即可登录后台。第二步学表单和 CSRF 防护。给网站加一个“发布文章”的页面让用户通过表单把数据写入数据库。这里会接触到 Django Form 或 ModelForm以及所有 POST 请求必须携带的 CSRF Token。第三步学模板继承。把页面公共部分抽出来用{% extends %}和{% block %}减少重复代码。这是所有 Django 模板工程化的基础。第四步学通用类视图Class-Based View。比如ListView、DetailView它们能把“查询列表 → 分页 → 渲染模板”这种重复逻辑封装好显著减少代码量。第五步学 Django REST Framework。如果你的项目需要给前端 App 或小程序提供接口DRF 是目前 Python 生态里最主流的方案之一。第六步学用户认证与权限。Django 内置的auth应用支持注册、登录、登出、权限分组这些是做业务系统绕不开的功能。在工程实践上还有几条忠告值得现在就知道settings.py里的SECRET_KEY绝对不能提交到公开代码仓库生产环境建议通过环境变量注入。项目上线后必须把DEBUG改成False并配置ALLOWED_HOSTS否则会暴露错误详情存在安全风险。开发时用 SQLite 没问题生产环境建议使用 PostgreSQL 或 MySQL并在切换前做好数据备份。runserver只适合开发调试生产环境需要搭配 gunicorn 或 uWSGI再由 Nginx 负责静态文件和反向代理。涉及数据库结构变更的操作务必先在测试环境验证再在确认备份可回滚的前提下执行。回到开头的问题Django 国内使用广泛吗答案是在 Python Web 领域Django 依然是成熟度和完整度最高的框架之一。它的学习曲线在前期略陡但一旦你抓住“请求响应闭环”这条主线后续每学一个新功能都是在给这条主线上加零件方向感会越来越清晰。现在最好的做法是关掉这篇文章打开终端把上面七步走一遍。跑通之后再进入 Admin 后台试试点一点、改一改数据你会发现 Django 真正强大的地方才刚刚开始。
返回列表