Django 入门到实战

Django 框架完全指南

本文档整合了多份 Django 学习笔记,经过系统化整理和补充,形成一份自包含、详尽且实用的 Django 开发手册。内容涵盖从基础概念到高级特性,包括模型层、视图层、模板层、表单、中间件、认证授权、日志、缓存、信号、测试、部署以及 Django REST framework 扩展等,适合开发者作为参考和深入学习使用。


目录

  1. Django 概述与安装
  2. 项目结构与配置
  3. URL 路由系统
  4. 视图层:处理请求与响应
  5. 模板层:页面渲染
  6. 模型层:ORM 数据库操作
  7. 表单与表单验证
  8. Admin 后台管理
  9. 中间件
  10. 认证与授权:Auth、Session、Cookie、CSRF
  11. 日志系统(Logging)
  12. 缓存(Redis 集成)
  13. 分页器(Paginator)
  14. 信号(Signals)
  15. 自定义管理命令
  16. 单元测试
  17. Django 请求生命周期与部署
  18. Django REST framework(DRF)扩展
  19. 异步任务:Celery 集成
  20. 调试工具:Django Debug Toolbar
  21. 补充专题

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, URLField
  • IntegerField, SmallIntegerField, BigIntegerField, FloatField, DecimalField
  • BooleanField, NullBooleanField
  • DateField, DateTimeField, TimeField, DurationField
  • FileField, ImageField (需设置 MEDIA_ROOT)
  • ForeignKey, ManyToManyField, OneToOneField

常见参数:

  • max_length:最大长度
  • null:是否允许数据库 NULL
  • blank:表单验证是否允许为空
  • 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, iendswith
  • in:包含于列表
  • gt, gte, lt, lte:比较
  • range:区间
  • isnull:是否为 NULL
  • year, 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 中合并)。
  • onlydefer:限制加载字段。
  • 使用 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

设置 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">&laquo; 第一页</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 }}">最后一页 &raquo;</a>
    {% endif %}
</div>

14. 信号(Signals)

信号允许在特定操作发生时执行回调函数,用于解耦业务逻辑。

14.1 内置信号

  • django.db.models.signals.pre_save / post_save
  • django.db.models.signals.pre_delete / post_delete
  • django.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 请求处理流程

  1. 客户端发送 HTTP 请求。
  2. WSGI 服务器(如 Gunicorn、uWSGI)接收请求并转换为 environ 字典。
  3. Django 的 WSGIHandler 加载中间件、路由等。
  4. 依次执行各个中间件的 process_request
  5. URL 路由匹配,找到视图函数/类。
  6. 执行中间件的 process_view
  7. 调用视图函数,可能涉及模型操作、模板渲染。
  8. 视图返回 HttpResponse 或异常。
  9. 如有异常,执行中间件的 process_exception
  10. 依次执行中间件的 process_response
  11. 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 文件上传处理

模型中使用 FileFieldImageField

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 等。
posted @ 2026-05-24 16:11  小郑[努力版]  阅读(40)  评论(0)    收藏  举报