Django 入门到实战
Django 框架完全指南
本文档整合了多份 Django 学习笔记,经过系统化整理和补充,形成一份自包含、详尽且实用的 Django 开发手册。内容涵盖从基础概念到高级特性,包括模型层、视图层、模板层、表单、中间件、认证授权、日志、缓存、信号、测试、部署以及 Django REST framework 扩展等,适合开发者作为参考和深入学习使用。
目录
- Django 概述与安装
- 项目结构与配置
- URL 路由系统
- 视图层:处理请求与响应
- 模板层:页面渲染
- 模型层:ORM 数据库操作
- 表单与表单验证
- Admin 后台管理
- 中间件
- 认证与授权:Auth、Session、Cookie、CSRF
- 日志系统(Logging)
- 缓存(Redis 集成)
- 分页器(Paginator)
- 信号(Signals)
- 自定义管理命令
- 单元测试
- Django 请求生命周期与部署
- Django REST framework(DRF)扩展
- 异步任务:Celery 集成
- 调试工具:Django Debug Toolbar
- 补充专题
1. Django 概述与安装
1.1 Django 简介
Django 是一个使用 Python 编写的开源 Web 框架,遵循 MTV(Model-Template-View)架构模式。其设计目标是快速开发、安全和可扩展。Django 内置了大量功能模块,如 ORM、表单处理、认证系统、Admin 后台、国际化支持等,因此被称为“大而全”的框架。
特点:
- 快速开发:内置脚手架、代码生成器。
- 安全性高:自动防范 XSS、CSRF、SQL 注入等常见攻击。
- 可伸缩性强:支持数据库读写分离、缓存、负载均衡等。
- 功能完善:自带 Admin、Session、分页、信号、缓存等。
1.2 安装 Django
pip install django
验证安装:
import django
print(django.get_version())
2. 项目结构与配置
2.1 创建项目
django-admin startproject mysite
cd mysite
项目目录结构:
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
asgi.py
2.2 创建应用(App)
python manage.py startapp myapp
应用目录结构:
myapp/
__init__.py
admin.py
apps.py
models.py
views.py
tests.py
migrations/
2.3 配置文件 settings.py 详解
常用配置项:
| 配置项 | 说明 |
|---|---|
DEBUG |
开发模式为 True,生产环境必须为 False |
ALLOWED_HOSTS |
允许访问的域名列表,生产环境需配置 |
INSTALLED_APPS |
注册应用(包括内置和自定义) |
MIDDLEWARE |
中间件列表 |
ROOT_URLCONF |
根 URL 配置模块 |
TEMPLATES |
模板引擎配置 |
DATABASES |
数据库连接配置 |
STATIC_URL / STATICFILES_DIRS |
静态文件 URL 和额外目录 |
MEDIA_URL / MEDIA_ROOT |
用户上传文件 URL 和存储根目录 |
LANGUAGE_CODE / TIME_ZONE |
语言和时区,中文设置为 'zh-hans' / 'Asia/Shanghai' |
USE_TZ |
是否启用时区支持,一般设为 False 以使用本地时间 |
2.4 数据库配置(以 MySQL 为例)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydb',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
同时需要在应用 __init__.py 中安装 PyMySQL:
import pymysql
pymysql.install_as_MySQLdb()
3. URL 路由系统
URL 路由将请求路径映射到视图函数或类。所有路由定义在 urlpatterns 列表中。
3.1 基本路由(path 和 re_path)
from django.urls import path, re_path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<int:year>/', views.year_archive),
re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
]
3.2 路径转换器
内置转换器:str, int, slug, uuid, path。
自定义转换器:
class FourDigitYearConverter:
regex = '[0-9]{4}'
def to_python(self, value):
return int(value)
def to_url(self, value):
return '%04d' % value
from django.urls import register_converter
register_converter(FourDigitYearConverter, 'yyyy')
3.3 路由分发(include)
from django.urls import include, path
urlpatterns = [
path('blog/', include('blog.urls')),
]
3.4 命名空间与反向解析
在子应用的 urls.py 中定义 app_name:
app_name = 'blog'
urlpatterns = [
path('', views.index, name='index'),
]
在模板中使用:
{% url 'blog:index' %}
在 Python 代码中:
from django.urls import reverse
url = reverse('blog:index')
4. 视图层:处理请求与响应
4.1 函数视图(FBV)与类视图(CBV)
FBV 示例:
from django.http import HttpResponse
def my_view(request):
return HttpResponse("Hello")
CBV 示例:
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")
路由中注册 CBV:
path('myview/', MyView.as_view()),
4.2 请求对象 HttpRequest
常用属性:
request.method:请求方法(GET, POST 等)request.GET:QueryDict,包含查询参数request.POST:QueryDict,包含表单数据(仅 POST)request.FILES:上传文件数据request.COOKIES:Cookie 字典request.session:会话对象request.user:当前用户(Auth 中间件提供)
4.3 响应对象 HttpResponse
常用子类:
HttpResponse:基础响应JsonResponse:JSON 响应FileResponse:文件响应HttpResponseRedirect:重定向(可使用redirect()快捷函数)
示例:
from django.http import JsonResponse
return JsonResponse({'status': 'ok'})
4.4 视图装饰器
| 装饰器 | 作用 |
|---|---|
@require_http_methods(['GET','POST']) |
限制允许的请求方法 |
@require_GET |
仅允许 GET |
@require_POST |
仅允许 POST |
@login_required |
必须登录才能访问 |
@csrf_exempt |
免除 CSRF 校验(慎用) |
4.5 快捷函数
render(request, template_name, context):渲染模板并返回 HttpResponse。redirect(to):重定向。get_object_or_404(klass, **kwargs):获取对象,不存在则抛出 404。
5. 模板层:页面渲染
Django 自带模板语言,支持变量、标签、过滤器和继承。
5.1 基本语法
- 变量:
{{ variable }},支持点号访问属性或字典键。 - 标签:
{% tag %},如{% if %},{% for %},{% url %},{% csrf_token %}。 - 过滤器:
{{ value|filter }},如{{ name|lower }}。
5.2 常用标签
| 标签 | 说明 |
|---|---|
{% if condition %}...{% endif %} |
条件判断 |
{% for item in list %}...{% endfor %} |
循环,支持 empty 子句 |
{% url 'name' arg %} |
反向解析 URL |
{% csrf_token %} |
输出 CSRF token 隐藏域 |
{% include "template.html" %} |
包含其他模板 |
{% extends "base.html" %} |
模板继承 |
{% block name %}...{% endblock %} |
定义可覆盖块 |
5.3 过滤器示例
| 过滤器 | 说明 |
|---|---|
| `{{ value | length }}` |
| `{{ value | default:"nothing" }}` |
| `{{ value | date:"Y-m-d" }}` |
| `{{ value | safe }}` |
| `{{ value | truncatechars:20 }}` |
5.4 模板继承
base.html:
<!DOCTYPE html>
<html>
<head><title>{% block title %}默认标题{% endblock %}</title></head>
<body>
{% block content %}{% endblock %}
</body>
</html>
child.html:
{% extends "base.html" %}
{% block title %}子页面标题{% endblock %}
{% block content %}
<p>这是内容</p>
{% endblock %}
5.5 静态文件处理
在 settings.py 中配置:
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / "static"] # 额外静态目录
模板中加载:
{% load static %}
<link rel="stylesheet" href="{% static 'css/style.css' %}">
6. 模型层:ORM 数据库操作
Django ORM 将数据库表映射为 Python 类,通过模型类进行数据操作。
6.1 定义模型
from django.db import models
class Student(models.Model):
SEX_CHOICES = ((0, '女'), (1, '男'), (2, '保密'))
name = models.CharField(max_length=20, db_index=True, verbose_name="姓名")
age = models.SmallIntegerField(verbose_name="年龄")
sex = models.SmallIntegerField(choices=SEX_CHOICES, default=2)
class_no = models.CharField(max_length=10, verbose_name="班级")
description = models.TextField(blank=True, null=True)
created_time = models.DateTimeField(auto_now_add=True)
updated_time = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'tb_student'
ordering = ['-created_time']
verbose_name = '学生'
verbose_name_plural = '学生'
def __str__(self):
return self.name
6.2 字段类型与参数
常用字段类型:
AutoField,BigAutoField:自增主键CharField,TextField,EmailField,URLFieldIntegerField,SmallIntegerField,BigIntegerField,FloatField,DecimalFieldBooleanField,NullBooleanFieldDateField,DateTimeField,TimeField,DurationFieldFileField,ImageField(需设置MEDIA_ROOT)ForeignKey,ManyToManyField,OneToOneField
常见参数:
max_length:最大长度null:是否允许数据库 NULLblank:表单验证是否允许为空default:默认值unique:唯一约束db_index:创建索引verbose_name:可读名称choices:选项列表on_delete:外键删除行为(CASCADE, PROTECT, SET_NULL, SET_DEFAULT, SET, DO_NOTHING)
6.3 关系字段
一对多(ForeignKey)
class Clas(models.Model):
name = models.CharField(max_length=32)
class Student(models.Model):
clas = models.ForeignKey(Clas, on_delete=models.CASCADE, related_name='students')
多对多(ManyToManyField)
class Course(models.Model):
name = models.CharField(max_length=32)
class Student(models.Model):
courses = models.ManyToManyField(Course, through='Enrollment') # 可指定中间表
class Enrollment(models.Model):
student = models.ForeignKey(Student, on_delete=models.CASCADE)
course = models.ForeignKey(Course, on_delete=models.CASCADE)
grade = models.CharField(max_length=2)
一对一(OneToOneField)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone = models.CharField(max_length=20)
6.4 数据库迁移
# 生成迁移文件
python manage.py makemigrations
# 执行迁移
python manage.py migrate
# 查看 SQL
python manage.py sqlmigrate app_name migration_number
6.5 基本增删改查
增加:
# 方式1:create
Student.objects.create(name='张三', age=20, class_no='301')
# 方式2:save
s = Student(name='李四', age=22)
s.save()
查询:
# 获取全部
students = Student.objects.all()
# 过滤
students = Student.objects.filter(age__gt=18, name__contains='张')
# 获取单个(不存在或超过一个会抛异常)
s = Student.objects.get(pk=1)
# 获取第一个/最后一个
first = Student.objects.first()
# 排除
excluded = Student.objects.exclude(age=20)
# 排序
ordered = Student.objects.order_by('-age', 'name')
# 切片
page1 = Student.objects.all()[:10]
更新:
# 方式1:单个对象 save
s = Student.objects.get(pk=1)
s.age = 21
s.save()
# 方式2:批量 update (返回受影响行数)
cnt = Student.objects.filter(age__lt=18).update(age=18)
删除:
# 单个删除
s = Student.objects.get(pk=1)
s.delete()
# 批量删除
Student.objects.filter(age__gt=30).delete()
6.6 字段查询(Field Lookups)
常用查询谓词(双下划线):
exact,iexact:精确/不区分大小写相等contains,icontains:包含startswith,istartswith,endswith,iendswithin:包含于列表gt,gte,lt,lte:比较range:区间isnull:是否为 NULLyear,month,day,week_day,hour,minute,second:日期时间部分
示例:
Student.objects.filter(birthday__year=2000)
Student.objects.filter(created_time__date='2024-01-01')
6.7 聚合与分组
聚合(aggregate):返回字典
from django.db.models import Avg, Count, Max, Min, Sum
result = Student.objects.aggregate(avg_age=Avg('age'), max_age=Max('age'))
# {'avg_age': 20.5, 'max_age': 30}
分组(annotate):返回 QuerySet,增加统计字段
# 每个班级的学生人数
clas_stats = Student.objects.values('class_no').annotate(cnt=Count('id'))
6.8 F 对象和 Q 对象
F 对象:引用字段值,用于字段间比较或避免竞态条件。
from django.db.models import F
# 年龄加1
Student.objects.update(age=F('age') + 1)
# 查询年龄大于班级号的学生
Student.objects.filter(age__gt=F('class_no'))
Q 对象:实现复杂查询(OR, NOT 等)。
from django.db.models import Q
# 年龄大于20 或 名字包含'张'
Student.objects.filter(Q(age__gt=20) | Q(name__contains='张'))
# 年龄不为18
Student.objects.filter(~Q(age=18))
6.9 原生 SQL
使用 raw():
students = Student.objects.raw('SELECT * FROM tb_student WHERE age > %s', [18])
使用 connection 直接执行:
from django.db import connection
with connection.cursor() as cursor:
cursor.execute("UPDATE tb_student SET age = age + 1")
6.10 查询优化
select_related:一次性获取外键关联对象(适用于一对一、一对多正向查询),减少查询次数。prefetch_related:为多对多或反向关系做预查询(使用额外查询并在 Python 中合并)。only和defer:限制加载字段。- 使用
exists()代替if queryset:来判断是否存在,避免加载整个结果集。 - 使用
iterator()处理大量数据,避免内存占用过大。
7. 表单与表单验证
7.1 Django Form
定义表单类:
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
视图处理:
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# 处理数据
return redirect('success')
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})
模板渲染:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">提交</button>
</form>
7.2 ModelForm
基于模型自动生成表单:
from django.forms import ModelForm
from .models import Student
class StudentForm(ModelForm):
class Meta:
model = Student
fields = ['name', 'age', 'class_no'] # 或 '__all__'
7.3 表单验证
在 clean_<fieldname> 或 clean 方法中添加自定义验证:
def clean_name(self):
name = self.cleaned_data['name']
if len(name) < 2:
raise forms.ValidationError("姓名太短")
return name
8. Admin 后台管理
8.1 注册模型
在 admin.py 中:
from django.contrib import admin
from .models import Student
@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
list_display = ('name', 'age', 'class_no', 'created_time')
list_filter = ('sex', 'class_no')
search_fields = ('name',)
ordering = ('-created_time',)
fields = ('name', 'age', 'sex', 'class_no', 'description') # 编辑表单显示字段
8.2 创建超级用户
python manage.py createsuperuser
访问 /admin 登录。
9. 中间件
中间件是一种在请求处理前后插入额外逻辑的钩子框架。每个中间件类可以实现以下一个或多个方法:
process_request(self, request):在处理视图之前调用。返回 None 继续,返回 HttpResponse 则中断。process_view(self, request, view_func, view_args, view_kwargs):在视图被调用之前调用。process_response(self, request, response):返回响应前调用,必须返回 response。process_exception(self, request, exception):视图抛出异常时调用。process_template_response(self, request, response):如果响应对象有render()方法,则在模板渲染前调用。
9.1 自定义中间件示例
from django.utils.deprecation import MiddlewareMixin
class SimpleMiddleware(MiddlewareMixin):
def process_request(self, request):
print("请求到达中间件")
def process_response(self, request, response):
print("响应离开中间件")
return response
注册到 MIDDLEWARE 列表。
9.2 常用内置中间件
SecurityMiddleware:安全增强SessionMiddleware:Session 支持CommonMiddleware:URL 斜杠重定向等CsrfViewMiddleware:CSRF 保护AuthenticationMiddleware:关联request.user
10. 认证与授权:Auth、Session、Cookie、CSRF
10.1 Cookie
设置 Cookie:
response.set_cookie('key', 'value', max_age=3600, httponly=True)
读取 Cookie:
value = request.COOKIES.get('key')
删除 Cookie:
response.delete_cookie('key')
10.2 Session
启用 Session(默认开启)。使用方式:
request.session['user_id'] = 1
user_id = request.session.get('user_id')
del request.session['user_id']
Session 配置项:
SESSION_ENGINE:存储后端(数据库、缓存、文件等)SESSION_COOKIE_AGE:过期时间(秒,默认 2 周)SESSION_EXPIRE_AT_BROWSER_CLOSE:关闭浏览器是否失效
10.3 用户认证(Auth 模块)
Django 内置 django.contrib.auth 提供用户模型和认证功能。
创建用户:
from django.contrib.auth.models import User
user = User.objects.create_user(username='john', password='secret')
认证登录:
from django.contrib import auth
user = auth.authenticate(request, username='john', password='secret')
if user:
auth.login(request, user) # 记录 session
登录装饰器:
from django.contrib.auth.decorators import login_required
@login_required
def profile(request):
...
登出:
auth.logout(request)
扩展用户模型:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
phone = models.CharField(max_length=11)
# settings.py
AUTH_USER_MODEL = 'myapp.User'
获取当前用户: request.user(未登录时为 AnonymousUser)
10.4 CSRF 防护
Django 默认启用 CSRF 中间件。在 POST 表单中必须包含 {% csrf_token %},或对于 AJAX 请求在请求头中设置 X-CSRFToken。
获取 CSRF Token 值:
from django.middleware.csrf import get_token
token = get_token(request)
全局禁用 CSRF 保护(不推荐):
@csrf_exempt
def my_view(request):
...
11. 日志系统(Logging)
Django 的日志基于 Python 标准库 logging,通过 LOGGING 字典配置。
11.1 配置示例
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
'style': '{',
},
'simple': {
'format': '{levelname} {message}',
'style': '{',
},
},
'filters': {
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': {
'console': {
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple',
},
'file': {
'level': 'WARNING',
'class': 'logging.handlers.RotatingFileHandler',
'filename': BASE_DIR / 'logs/django.log',
'maxBytes': 1024 * 1024 * 50, # 50MB
'backupCount': 5,
'formatter': 'verbose',
},
},
'loggers': {
'django': {
'handlers': ['console', 'file'],
'level': 'INFO',
'propagate': True,
},
'myapp': {
'handlers': ['console', 'file'],
'level': 'DEBUG',
'propagate': False,
},
},
'root': {
'handlers': ['console'],
'level': 'WARNING',
},
}
11.2 在代码中使用
import logging
logger = logging.getLogger(__name__)
logger.debug("调试信息")
logger.info("普通信息")
logger.warning("警告")
logger.error("错误", exc_info=True)
11.3 内置 Logger
django.request:记录请求处理日志,5xx 错误为 ERROR,4xx 为 WARNING。django.server:开发服务器请求日志。django.db.backends:记录 SQL 语句(需设置 DEBUG 级别)。django.security:安全相关事件。
12. 缓存(Redis 集成)
Django 支持多种缓存后端,最常用的是 Redis。
12.1 安装与配置
pip install django-redis
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
}
}
}
12.2 全站缓存
添加中间件:
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
...
'django.middleware.cache.FetchFromCacheMiddleware',
]
设置缓存时长:
CACHE_MIDDLEWARE_SECONDS = 600 # 10分钟
12.3 视图缓存
from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def my_view(request):
...
12.4 模板片段缓存
{% load cache %}
{% cache 500 sidebar %}
<!-- 缓存内容 -->
{% endcache %}
12.5 低级缓存 API
from django.core.cache import cache
cache.set('key', 'value', timeout=60)
value = cache.get('key')
cache.delete('key')
12.6 Session 缓存
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default'
13. 分页器(Paginator)
from django.core.paginator import Paginator
def book_list(request):
books = Book.objects.all()
paginator = Paginator(books, 10) # 每页10条
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number) # 处理无效页码
return render(request, 'books.html', {'page_obj': page_obj})
模板中:
{% for book in page_obj %}
{{ book.title }}
{% endfor %}
<div class="pagination">
{% if page_obj.has_previous %}
<a href="?page=1">« 第一页</a>
<a href="?page={{ page_obj.previous_page_number }}">上一页</a>
{% endif %}
<span>第 {{ page_obj.number }} / {{ page_obj.paginator.num_pages }} 页</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">下一页</a>
<a href="?page={{ page_obj.paginator.num_pages }}">最后一页 »</a>
{% endif %}
</div>
14. 信号(Signals)
信号允许在特定操作发生时执行回调函数,用于解耦业务逻辑。
14.1 内置信号
django.db.models.signals.pre_save/post_savedjango.db.models.signals.pre_delete/post_deletedjango.core.signals.request_started/request_finished
14.2 定义接收器
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import UserProfile, User
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
14.3 注册信号
通常将信号连接放在应用配置类的 ready() 方法中:
# apps.py
from django.apps import AppConfig
class MyappConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'myapp'
def ready(self):
import myapp.signals
15. 自定义管理命令
在应用的 management/commands/ 目录下创建 Python 脚本。
# management/commands/import_data.py
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = '导入 CSV 数据'
def add_arguments(self, parser):
parser.add_argument('file_path', type=str)
def handle(self, *args, **options):
file_path = options['file_path']
# 处理逻辑
self.stdout.write(self.style.SUCCESS('导入成功'))
运行:
python manage.py import_data /path/to/data.csv
16. 单元测试
Django 基于 Python unittest 提供测试框架。
16.1 编写测试
from django.test import TestCase, Client
from django.urls import reverse
from .models import Student
class StudentTestCase(TestCase):
def setUp(self):
Student.objects.create(name='张三', age=20)
def test_student_creation(self):
student = Student.objects.get(name='张三')
self.assertEqual(student.age, 20)
def test_view_response(self):
client = Client()
response = client.get(reverse('student_list'))
self.assertEqual(response.status_code, 200)
16.2 运行测试
python manage.py test myapp
17. Django 请求生命周期与部署
17.1 请求处理流程
- 客户端发送 HTTP 请求。
- WSGI 服务器(如 Gunicorn、uWSGI)接收请求并转换为
environ字典。 - Django 的
WSGIHandler加载中间件、路由等。 - 依次执行各个中间件的
process_request。 - URL 路由匹配,找到视图函数/类。
- 执行中间件的
process_view。 - 调用视图函数,可能涉及模型操作、模板渲染。
- 视图返回
HttpResponse或异常。 - 如有异常,执行中间件的
process_exception。 - 依次执行中间件的
process_response。 - WSGI 服务器将响应发送给客户端。
17.2 部署建议
- 设置
DEBUG = False,配置ALLOWED_HOSTS。 - 使用
Gunicorn+Nginx进行生产部署。 - 静态文件收集:
python manage.py collectstatic。 - 使用数据库连接池、缓存、CDN 等优化性能。
- 配置日志记录错误信息。
18. Django REST framework(DRF)扩展
DRF 是 Django 下的 API 开发工具包,提供了序列化、视图集、认证、权限、分页、过滤等组件。
18.1 安装与配置
pip install djangorestframework
在 settings.py 中注册:
INSTALLED_APPS = [
...
'rest_framework',
]
18.2 序列化器(Serializer)
from rest_framework import serializers
from .models import Student
class StudentSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = ['id', 'name', 'age', 'class_no']
18.3 视图集与路由
from rest_framework.viewsets import ModelViewSet
from .models import Student
from .serializers import StudentSerializer
class StudentViewSet(ModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentSerializer
注册路由:
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('students', StudentViewSet)
urlpatterns += router.urls
18.4 认证与权限
认证失败返回 401:使用 AuthenticationFailed 异常。
from rest_framework.exceptions import AuthenticationFailed
if not token:
raise AuthenticationFailed(detail="无效token", code="invalid_token")
常用认证类:TokenAuthentication, SessionAuthentication, JWTAuthentication。
权限类:IsAuthenticated, IsAdminUser, AllowAny。
18.5 过滤与排序
内置过滤:
from rest_framework.filters import SearchFilter, OrderingFilter
class StudentViewSet(ModelViewSet):
filter_backends = [SearchFilter, OrderingFilter]
search_fields = ['name', 'class_no']
ordering_fields = ['age', 'id']
DjangoFilterBackend(精确过滤):
from django_filters.rest_framework import DjangoFilterBackend
class StudentViewSet(ModelViewSet):
filter_backends = [DjangoFilterBackend]
filterset_fields = ['class_no', 'sex']
18.6 分页
全局配置:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10
}
自定义分页类:
class CustomPagination(PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 100
18.7 全局异常处理
DRF 默认的 exception_handler 只处理 APIException 子类。可以自定义:
# utils.py
from rest_framework.views import exception_handler
from rest_framework.response import Response
def custom_exception_handler(exc, context):
response = exception_handler(exc, context)
if response is not None:
response.data = {
'code': response.status_code,
'message': response.data.get('detail', '请求错误')
}
else:
response = Response({'code': 500, 'message': '服务器内部错误'}, status=500)
return response
配置:
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'myapp.utils.custom_exception_handler'
}
19. 异步任务:Celery 集成
Celery 是一个分布式任务队列,用于处理异步任务和定时任务。
19.1 安装与配置
pip install celery redis
在项目目录下创建 celery.py:
import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
app = Celery('mysite')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
在 __init__.py 中加载:
from .celery import app as celery_app
__all__ = ['celery_app']
settings.py 配置:
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
19.2 定义任务
在应用下的 tasks.py 中:
from celery import shared_task
@shared_task
def add(x, y):
return x + y
19.3 调用任务
from myapp.tasks import add
result = add.delay(4, 5) # 异步执行
print(result.id)
获取结果:
from celery.result import AsyncResult
res = AsyncResult(task_id)
if res.ready():
print(res.get())
19.4 定时任务(Beat)
在 settings.py 中配置:
from celery.schedules import crontab
CELERY_BEAT_SCHEDULE = {
'every-30-seconds': {
'task': 'myapp.tasks.add',
'schedule': 30.0,
'args': (1, 2),
},
'every-day-at-midnight': {
'task': 'myapp.tasks.clear_cache',
'schedule': crontab(hour=0, minute=0),
},
}
启动 Worker 和 Beat:
celery -A mysite worker -l info
celery -A mysite beat -l info
20. 调试工具:Django Debug Toolbar
用于开发环境查看 SQL、请求、模板等信息。
20.1 安装与配置
pip install django-debug-toolbar
settings.py:
INSTALLED_APPS += ['debug_toolbar']
MIDDLEWARE.insert(0, 'debug_toolbar.middleware.DebugToolbarMiddleware')
INTERNAL_IPS = ['127.0.0.1']
urls.py(仅当 DEBUG=True):
from django.conf import settings
from django.urls import include, path
if settings.DEBUG:
import debug_toolbar
urlpatterns = [
path('__debug__/', include(debug_toolbar.urls)),
] + urlpatterns
20.2 面板功能
提供 SQL 语句、请求、模板、缓存、性能分析等面板,帮助定位性能瓶颈和代码问题。
21. 补充专题
21.1 FBV 与 CBV 的选择
- FBV:简单、直观,适合小型视图。
- CBV:利用继承和 Mixin,适合复用逻辑(如
ListView,DetailView,CreateView)。
21.2 文件上传处理
模型中使用 FileField 或 ImageField:
class Document(models.Model):
file = models.FileField(upload_to='docs/')
表单中需要设置 enctype="multipart/form-data"。视图处理:
def upload(request):
if request.method == 'POST':
doc = Document(file=request.FILES['file'])
doc.save()
...
21.3 信号的实际应用
常见场景:创建用户时自动创建 Profile;记录模型变更日志;清除缓存等。
21.4 使用原生 Python 的线程/协程/进程
Django 本身是同步框架,但可通过以下方式实现并发:
- 使用
concurrent.futures.ThreadPoolExecutor执行耗时任务(注意数据库连接安全)。 - 使用
asyncio配合 Django 3.1+ 的异步视图(需要 ASGI 服务器)。 - 使用
multiprocessing进行 CPU 密集型计算(注意数据库连接隔离)。 - 推荐将长时间任务交给 Celery 处理。
21.5 WSGI 与 ASGI
- WSGI:同步 Web 服务器网关接口,Django 默认使用。
- ASGI:异步服务器网关接口,支持 WebSocket 和长连接。Django 3.0+ 支持 ASGI,可用于 Channels 等。

浙公网安备 33010602011771号