Django+Vue 学习日志(01路由)
PART01:从零搭建到路由系统
记录时间:2026年7月30日
环境:Fedora 44 + Python 3.12.13 + Django 5.2.16
前言
最近开始系统学习 Django + Vue 前后端分离开发,这篇日志记录了第一天踩过的坑和学到的核心概念。从环境搭建到第一个接口跑通,再到嵌套路由的理解,算是把 Django 的骨架摸清楚了。
一、项目结构与导入机制
目录结构
DJANGO_DEMO/
└── demo/
├── manage.py
├── app01/
│ ├── views.py
│ ├── models.py
│ └── ...
├── app02/
├── demo/
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── db.sqlite3
这个项目结构有两个 demo 目录,外层是项目根目录(manage.py 所在位置),内层是 Django 的配置包。这是 django-admin startproject 生成的默认结构,刚开始确实容易绕晕。
导入路径的本质
Python 的导入路径取决于 sys.path,而 manage.py 所在目录会被自动加入 sys.path 首位。因此 app01 可以直接导入,不需要写成 demo.app01。
推荐的导入风格:
from app01 import views
urlpatterns = [
path('hello/', views.helloworld),
]
统一用 模块.函数 的方式,多个 app 时可读性更好,也是 Django 社区的主流写法。
二、视图层基础
HttpResponse vs render
| 导入 | 类型 | 作用 |
|---|---|---|
HttpResponse |
类 | 最底层,直接构造 HTTP 响应 |
render |
函数 | 高级封装,加载模板 → 渲染 → 包装成 HttpResponse |
# 返回纯文本
return HttpResponse("Hello World!")
# 渲染模板(前后端分离项目中较少使用)
return render(request, 'index.html', {'name': '张三'})
由于走的是前后端分离路线,后续主要用 JsonResponse 返回 JSON 数据给 Vue 前端消费。
三、嵌套路由系统
这是今天理解最透彻的一块。嵌套路由的核心是 include(),通过分层管理 URL,让每个 app 自己管自己的路由。
主路由(项目级)
# demo/demo/urls.py
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('article/', include('app01.urls')),
]
子路由(应用级)
# app01/urls.py
from django.urls import path
from app01 import views
urlpatterns = [
path('create/', views.article_create, name='article_create'),
path('<int:article_id>/', views.article_detail, name='article_detail'),
path('hello/', views.helloworld, name='hello'),
]
请求匹配流程
请求: /article/1/
↓
主路由匹配 article/,剩余部分交给 app01.urls
↓
子路由匹配 <int:article_id>/,调用 article_detail
↓
article_detail(request, article_id=1)
一个容易踩的坑
主路由末尾的 / 不是可有可无的:
path('article/', include('app01.urls')) # ✅ 推荐
path('article', include('app01.urls')) # ⚠️ 能跑但语义混乱
没有斜杠时,Django 会把 article 和子路由拼接后再匹配,比如 /articlehello 也能命中 hello/ 路由,逻辑上很绕。
四、URL 参数捕获
path('article/<int:article_id>/', views.article_detail, name='article_detail')
def article_detail(request, article_id):
return HttpResponse(f'这是第{article_id}篇文章的内容')
Django 内置的转换器:
| 转换器 | 匹配内容 |
|---|---|
int |
正整数 |
str |
除 / 外的字符串 |
slug |
字母数字、-、_ |
uuid |
UUID 格式 |
path |
包含 / 的字符串 |
int 转换器会自动做类型转换,用户输入 /article/abc/ 直接返回 404,不用手动校验。
五、name 参数的作用
name 给路由起一个内部代号,用于反向解析 URL,避免在代码和模板中硬编码路径。
path('create/', views.article_create, name='article_create')
# Python 代码中
from django.shortcuts import redirect
redirect('article_create')
# 模板中
<a href="{% url 'article_create' %}">新建文章</a>
改 URL 路径时只需修改 urls.py,其他地方自动生效。前后端分离项目中虽然模板用得少,但后端重定向场景仍然有用。
六、踩坑记录
| 坑 | 原因 | 解决 |
|---|---|---|
ModuleNotFoundError: No module named 'demo.app01' |
误以为 app01 在内层 demo 目录中 | 改为 from app01 import views |
NameError: name 'helloworld' is not defined |
导入的是模块却直接用函数名 | 改为 views.helloworld |
NameError: name 'HttpResponse' is not defined |
导入语句被删或未保存文件 | 补上导入并保存 |
| URL 匹配混乱 | 主路由末尾缺 / |
改为 path('article/', include(...)) |
article 拼写错误 |
artical 少了 cle |
统一改为 article |
其中最离谱的是"代码没保存"……改完记得 Ctrl+S 是程序员第一课 😂
七、今日成果
| URL | 视图函数 | 响应内容 |
|---|---|---|
/hello/ |
helloworld |
Hello World! |
/article/create/ |
article_create |
这是文章1的内容 |
/article/1/ |
article_detail |
这是第1篇文章的内容 |
从环境搭建到第一个接口跑通,再到嵌套路由的理解,一天下来 Django 的基础骨架已经摸清了。
八、下一步计划
- POST 请求处理:表单数据、CSRF
小结
导入路径看
sys.path,不看文件位置。 嵌套路由的核心是include(),主路由管分发,子路由管细节。URL 路径是给用户的,name是给代码的。改完代码记得保存。
明天继续 💪

浙公网安备 33010602011771号