注意:一定要动手从0到1的实操项目,项目网上很多,
一篇带你搞懂Django核心概念、项目结构、数据库操作与常见进阶技巧的完整笔记
引言:从静态网页到动态网页
早期的网页都是静态的------你请求什么,服务器就返回什么,内容不会因人、因时而变。而现在的网站几乎都是动态网页:登录后显示你的名字、推荐个性化内容、实时刷新数据......
这背后离不开Web服务器 和HTTP协议。
当我们用浏览器访问一个网站时,浏览器(客户端)会向服务器发送一段符合HTTP协议的数据,格式如下:
text
POST /api/user/login HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 ...
Content-Type: application/x-www-form-urlencoded
username=admin&password=123456
服务器收到后需要:
-
解析请求行(方法、路径、协议版本)
-
解析请求头(浏览器信息、编码等)
-
解析请求体(表单数据)
-
执行业务逻辑
-
返回响应
如果每次都要手动写Socket、解析HTTP报文,开发效率极低。Web框架就是来解决这个问题的。
在Python生态中,最著名的Web框架之一就是 Django。
一、Django概述与环境搭建
1.1 什么是Django?
Django是一个高级Python Web框架,遵循"开箱即用"哲学。它内置了:
-
ORM(对象关系映射)
-
路由系统
-
模板引擎
-
表单处理
-
认证系统
-
后台管理(Admin)
适合快速开发安全、可维护的网站。
1.2 安装Django
bash
pip install Django==4.2
查看版本:
bash
python -m django --version
1.3 创建项目
方式一:命令行
bash
django-admin startproject myproject
cd myproject
python manage.py runserver # 默认8000端口
python manage.py runserver 8080 # 指定端口
方式二:PyCharm专业版
直接选择 Django 项目模板,IDE会自动创建项目结构和虚拟环境。
二、Django项目结构详解
创建好的项目目录如下:
text
myproject/
├── manage.py
├── myproject/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
│ └── asgi.py
├── app/ # 手动或自动创建的业务模块
│ ├── migrations/
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── views.py
│ └── tests.py
├── templates/ # 存放HTML文件
├── static/ # 存放CSS/JS/图片(需手动创建并配置)
└── db.sqlite3 # 默认数据库
2.1 核心文件介绍
| 文件/目录 | 作用 |
|---|---|
manage.py |
Django的命令行工具,不要改动 |
settings.py |
项目配置文件:注册APP、数据库、静态资源、中间件等 |
urls.py |
总路由:哪个URL由哪个视图函数处理 |
views.py |
视图:写业务逻辑的地方(最常改) |
models.py |
模型:定义数据库表结构 |
admin.py |
注册模型到Django自带后台 |
templates/ |
存放HTML模板 |
static/ |
存放静态资源(CSS/JS/图片) |
2.2 静态资源配置
如果在项目根目录下创建了 static 文件夹,需要在 settings.py 中添加:
python
import os
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static")
]
2.3 创建一个APP(业务模块)
bash
python manage.py startapp user
然后在 settings.py 的 INSTALLED_APPS 中加入 'user'。
三、Django运行逻辑(重点)
一个完整的请求-响应流程:
-
浏览器访问
http://127.0.0.1:8000/login/ -
Django找到
urls.py,匹配到path('login/', views.login) -
执行
views.py中的login函数 -
函数可能查询数据库(
models.py) -
函数返回渲染后的HTML(
templates/login.html) -
浏览器显示页面,同时加载
static/style.css
一句话总结:urls 指路 → views 干活 → models 存数据 → templates 展示 → static 美化
四、新手常见错误与解决
| 错误现象 | 原因及解决方案 |
|---|---|
Page not found (404),提示缺少末尾斜杠 |
POST表单的 action="/login" 缺少结尾 /,改为 /login/ |
Forbidden (403) CSRF verification failed |
表单中没有加 {% csrf_token %},在 <form> 内加上即可 |
login() takes 0 positional arguments... |
视图函数缺少 request 参数,改为 def login(request): |
'str' object has no attribute 'get' |
对字符串调用了 .get(),检查变量类型,可能把POST数据当成了字符串 |
局部变量 'xxx' referenced before assignment |
变量作用域问题,确保变量在使用前已被赋值 |
视图函数没有return,报错 returned None |
所有分支都必须 return HttpResponse 或 render 等 |
五、数据库与ORM
Django内置了ORM(对象关系映射),让你用Python类来操作数据库,无需手写SQL。
5.1 配置MySQL数据库
修改 settings.py:
python
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydb',
'HOST': '127.0.0.1',
'PORT': '3306',
'USER': 'root',
'PASSWORD': '123456',
}
}
5.2 安装驱动并配置
在与 settings.py 同目录的 __init__.py 中写入:
python
import pymysql
pymysql.install_as_MySQLdb()
5.3 定义模型(models.py)
python
from django.db import models
class User(models.Model):
id = models.AutoField(primary_key=True)
username = models.CharField(max_length=30, unique=True)
password = models.CharField(max_length=30)
age = models.IntegerField(default=0)
5.4 生成并同步数据库
bash
python manage.py makemigrations # 生成迁移文件
python manage.py migrate # 真正同步到数据库
每次修改
models.py后,都需要重新执行上面两条命令。
5.5 在视图中使用ORM
python
from django.shortcuts import render, redirect
from .models import User
def register(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if User.objects.filter(username=username).exists():
return render(request, 'register.html', {'msg': '用户名已存在'})
User.objects.create(username=username, password=password)
return redirect('/login/')
return render(request, 'register.html')
常用ORM操作:
-
User.objects.all()查询所有 -
User.objects.filter(条件)条件查询 -
User.objects.get(id=1)获取单个对象 -
user.save()保存修改 -
user.delete()删除
六、技术拓展
6.1 Ajax异步交互
传统表单提交会刷新整个页面 ,而Ajax可以在不刷新页面的情况下与服务器交换数据,实现局部更新。
前端示例(使用jQuery):
javascript
$.ajax({
url: "/check_username/",
type: "POST",
data: { username: "alice" },
headers: { "X-CSRFToken": $('input[name="csrfmiddlewaretoken"]').val() },
success: function(res) {
if (res.exists) {
alert("用户名已存在");
}
}
});
后端视图:
python
from django.http import JsonResponse
def check_username(request):
username = request.POST.get('username')
exists = User.objects.filter(username=username).exists()
return JsonResponse({'exists': exists})
注意:POST请求需要处理CSRF,可以在表单中放
{% csrf_token %},然后通过JS获取其值加到请求头。
6.2 函数视图 vs 类视图
| 类型 | 特点 |
|---|---|
| FBV(函数视图) | 简单直观,适合小型逻辑。def my_view(request): |
| CBV(类视图) | 可复用、结构清晰,通过继承内置类(如 ListView、CreateView)减少代码量。 |
类视图示例:
python
from django.views import View
from django.http import HttpResponse
class MyView(View):
def get(self, request):
return HttpResponse('GET请求')
def post(self, request):
return HttpResponse('POST请求')
路由中需使用 .as_view():path('some/', MyView.as_view())
6.3 转发 vs 重定向
| 操作 | 函数 | 地址栏变化 | 适用场景 |
|---|---|---|---|
| 转发 | render(request, 'a.html') |
不变 | 查询数据并展示页面 |
| 重定向 | redirect('/login/') |
会变 | 表单提交后跳转,防止重复提交 |
表单提交成功后必须用重定向,否则用户刷新页面会重复提交!
6.4 MVT设计模式
Django遵循 MVT 模式(类似MVC):
-
M(Model) :模型,负责数据存取(
models.py) -
V(View) :视图,负责业务逻辑(
views.py) -
T(Template) :模板,负责页面展示(
templates/)
text
用户请求 → urls(路由) → View(处理逻辑) → Model(读写数据) → Template(渲染) → 响应
6.5 Session 与 Cookie
-
Cookie:存储在浏览器端,每次请求自动携带,大小有限(4KB)
-
Session :存储在服务器端,通过Cookie中的
sessionid关联,更安全
登录流程示例:
python
def login(request):
if request.method == 'POST':
user = authenticate(username=..., password=...)
if user:
request.session['user_id'] = user.id # 写入session
return redirect('/home/')
在其他视图中获取登录用户:
python
user_id = request.session.get('user_id')
if not user_id:
return redirect('/login/')
依赖
SessionMiddleware(默认已开启)。
6.6 Django中间件
中间件是Django请求/响应的全局钩子,所有请求都会经过它。
常见中间件:
-
SessionMiddleware:支持Session -
CsrfViewMiddleware:CSRF防护 -
AuthenticationMiddleware:关联用户与请求
自定义中间件实现全局登录校验:
python
# middleware.py
from django.shortcuts import redirect
from django.urls import reverse
class LoginRequiredMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# 白名单路径不需要登录
whitelist = ['/login/', '/register/']
if not request.path in whitelist and not request.session.get('user_id'):
return redirect('/login/')
return self.get_response(request)
然后在 settings.py 的 MIDDLEWARE 列表中注册。
七、总结
通过这份笔记,你应该已经掌握了:
-
Django项目结构及各文件职责
-
完整的请求处理流程(urls → views → models → templates)
-
常见错误的快速定位与解决
-
数据库配置与ORM基本使用
-
进阶技术:Ajax、类视图、重定向、Session、中间件
学习Django最好的方式就是动手实践:从一个简单的博客系统或待办清单开始,逐步加入用户认证、评论功能、后台管理等。遇到问题不要怕,多看错误提示,多查官方文档。
每一段代码的报错,都是你通往熟练的阶梯。