关于 django-best-practices
面向 Django 应用开发与审查的技能,覆盖 28 个主题领域。它通过正反代码示例和参考资料,提供从 ORM 到部署的实践指引。
主要功能
- 01覆盖 28 个 Django 主题
- 02提供正反代码示例
- 03ORM 查询与性能实践
- 04安全、测试和部署指引
适用场景
- 01审查 Django 模型、视图或迁移
- 02优化 ORM 查询并处理 N+1 问题
- 03检查应用安全与部署配置
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ ahmetcdincer/ django-skills --skill django-best-practices安装后在 Claude Code 中输入/django-best-practices确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/admin.mdarchitecture.mdasync.mdauth.mdcaching.mdcelery.mdchannels.mdcore.mddeployment.mddrf.mdecosystem.mdemail.mdforms.mdi18n.mdlogging.mdmessages.mdmiddleware.mdmigrations.mdmodels.mdpagination.mdqueries.mdsecurity.mdsignals.mdstatic-media.mdtemplates.mdtesting.mdurls.mdviews.md详细介绍
Django 最佳实践
资深 Django 开发者的知识库,涵盖 28 个主题领域——从 ORM 查询到部署,内容更新至 Django 6.0。本技能提供错误与正确的代码示例,以及构建生产级 Django 应用的架构指导。
何时使用本技能
- 创建或修改 Django 模型、字段或关系
- 编写视图(FBV、CBV 或 DRF ViewSet)
- 构建或更新 DRF 序列化器和 API 端点
- 编写 ORM 查询、修复 N+1 问题或优化性能
- 创建或审查迁移
- 配置 Django 设置、中间件或 URL 路由
- 实现身份验证、权限或会话管理
- 设置缓存(Redis、Memcached、按视图缓存、片段缓存)
- 编写或审查测试(Django TestCase、pytest、工厂)
- 使用 Django 信号、表单、模板或模板标签
- 配置静态文件/媒体文件、文件上传或存储后端
- 设置后台任务(Celery 或 Django 6.0 原生的 django.tasks)
- 部署 Django(Gunicorn、Nginx、Docker、CI/CD)
- 使用 Django Channels 或 WebSocket
- 编写异步视图或使用异步 ORM
- 实现 i18n/l10n 或时区支持
- 审查代码中的安全问题(CSRF、XSS、SQL 注入、CSP)
- 对查询集分页、发送电子邮件、配置日志或闪现消息
- 设计应用架构、服务层或项目结构
工作流
激活本技能后,请遵循以下步骤:
- 确定主题——判断任务涉及 Django 的哪个领域(模型、视图、查询等)
- 阅读相关参考文件——查阅下方的参考表,并在编写任何代码前阅读相应文件
- 应用正确模式——遵循参考文件中的“正确”模式,避免“错误”的反模式
- 检查常见错误——阅读“原因”说明,了解每种模式背后的依据
- 交叉参考相关主题——如果任务涉及多个领域(例如视图 + 查询 + 模板),请阅读所有相关参考文件
编写该主题的代码前,务必先阅读相关参考文件。
核心原则
项目结构
- 将配置与应用分开。使用
config/settings/,包含 base、local 和 production 文件。 - 保持应用小而专注(每个应用包含 3-8 个模型)。应用超过 15 个模型时应拆分。
- 务必在首次迁移前设置
AUTH_USER_MODEL。 - 通过
settings.AUTH_USER_MODEL引用用户,切勿直接使用auth.User。
模型与 ORM
- 金额使用
DecimalField,标志位使用BooleanField,电子邮件使用EmailField。 - 切勿在
CharField/TextField上设置null=True——可选字符串只使用blank=True。 - 枚举字段使用
TextChoices/IntegerChoices,切勿使用魔法字符串。 - 始终为 ForeignKey 和 OneToOneField 设置显式的
related_name。 - ForeignKey/OneToOne 使用
select_related,ManyToMany/反向 FK 使用prefetch_related。 - 使用
F()表达式执行原子更新,避免竞态条件。 - 检查是否存在时,使用
Exists(),不要使用.count() > 0。 - 批量操作使用
bulk_create和bulk_update。 - 多步写操作使用
transaction.atomic()包裹。
查询
- 数据库能够执行的筛选,切勿放在 Python 中进行。
- OR/NOT 查询使用
Q对象。 - 使用
annotate和Subquery,替代 N+1 循环。 - 原始 SQL 务必使用参数化查询,切勿使用 f-string。
- 不需要完整模型实例时,使用
.values_list()。 - 使用
.exists(),不要使用.count() > 0。 - 大型查询集使用
.iterator()。
视图
- 简单的一次性视图使用 FBV,带泛型的 CRUD 使用 CBV。
- 受保护的视图务必使用
LoginRequiredMixin或@login_required。 - 在 UpdateView/DeleteView 中重写
get_queryset()以强制执行所有权校验。 - 视图中使用
get_object_or_404;预期对象可能不存在时使用.first()。
表单与验证
- 在 ModelForm 中始终显式指定
fields,绝不使用exclude或__all__。 - 单字段验证使用
clean_<field>(),跨字段验证使用clean()。 - 使用 Django 内置验证器,并针对领域规则编写自定义验证器。
安全
- 除了使用自身身份验证机制的外部 Webhook,绝不禁用 CSRF。
- 绝不对用户输入使用
mark_safe()或|safe,应使用format_html()。 - 绝不在原始 SQL 中使用 f-string,始终使用参数化查询。
- 使用 Argon2 进行密码哈希,PBKDF2 作为后备方案。
- 在生产环境中设置
SECURE_SSL_REDIRECT、SECURE_HSTS_*和 Cookie 安全标志。 - 配置内容安全策略(
SECURE_CSP,自 Django 6.0 起内置)。 - 使用
django.core.signing生成有过期时间的令牌,绝不手动编写哈希方案。 - 对登录进行速率限制,并在面向互联网的网站上将管理后台移出
/admin/。 - 每次部署前运行
manage.py check --deploy。
身份验证
- 优先使用
LoginRequiredMiddleware(Django 5.1+),并通过@login_not_required设置例外,而不是在各个视图上使用 mixin,确保默认安全。
管理后台
- 始终配置
list_display、list_filter和search_fields。 - 使用
list_select_related,避免列表视图出现 N+1 查询。 - 对计算得出或自动生成的值使用
readonly_fields。 - 重写权限方法,限制工作人员可执行的操作。
模板
- 使用
base.html和{% block %}标签进行模板继承。 - 始终使用
{% url %}和{% static %},绝不硬编码路径。 - 在 for 循环中使用
{% empty %},在开销较大的查询中使用{% with %}。 - 绝不使用
{% autoescape off %},也绝不对用户内容使用|safe。
迁移
- 编写小型、专注且名称明确的迁移。
- 自定义迁移和数据迁移始终提供反向操作。
- 在数据迁移中使用
apps.get_model(),绝不直接导入模型。 - 分步删除列:先设为可为空 → 部署 → 删除。
- 在生产环境运行迁移前使用
--plan预览迁移计划。
测试
- 无需数据库的测试使用
SimpleTestCase,数据库测试使用TestCase。 - 使用
setUpTestData设置类级别的测试数据(比setUp更快)。 - 使用 factory_boy 代替 JSON 固定数据。
- 模拟外部服务(短信、支付、API)。
- 使用
@override_settings和 Django 的locmem邮件后端进行测试。 - 业务逻辑的覆盖率目标为 80% 以上。
DRF
- 在序列化器中始终显式指定
fields,绝不使用__all__。 - 对嵌套数据使用独立的读写序列化器。
- 将
IsAuthenticated设为全局默认权限。 - 始终为列表端点启用分页。
- 使用
django-filter声明式筛选。 - 使用
select_related/prefetch_related优化get_queryset()。
信号
- 在
AppConfig.ready()中导入信号,绝不在模块级别导入。 - 使用
dispatch_uid防止重复连接。 - 对紧密耦合的逻辑,优先使用显式方法调用,而不是信号。
- 信号仅用于解耦的跨应用通信。
缓存
- 开发环境使用
DummyCache,生产环境使用 Redis。 - 使用带命名空间且设置了超时的缓存键。
- 仅使目标缓存键失效,绝不调用
cache.clear()。 - 在合理范围内尽可能采用细粒度缓存。
部署
- 绝不在生产环境使用
runserver,应使用 Gunicorn 或 Uvicorn。 - 使用多阶段 Docker 构建。
- 将密钥存储在环境变量中,绝不写入代码。
- 使用 Gunicorn HUP 信号实现零停机部署。
- 始终提供健康检查端点。
后台任务
- 向任务传递 ID,绝不传递模型实例。
- 始终使用指数退避实现重试逻辑。
- 确保任务幂等,可安全地多次运行。
- 使用
@shared_task,而不是直接导入 Celery 应用。 - 对于简单的任务卸载,在引入 Celery 前考虑使用 Django 6.0 原生的
django.tasks。 - 通过
transaction.on_commit()在事务内部将任务加入队列。
日常必备
- 使用
paginator.get_page()进行分页,并始终先调用order_by();在链接中使用{% querystring %}保留筛选条件。 - 使用按环境配置的后端,从后台任务发送电子邮件;始终包含纯文本部分。
- 使用
disable_existing_loggers: False配置LOGGING,并在模块级别使用getLogger(__name__)——切勿使用print()。 - 使用 messages 框架,并采用 post/redirect/get 模式向用户提供反馈。
- 使用锁定文件(pip-tools/uv)固定依赖项;提交编译后的输出。
参考文件
为相关主题编写代码前,请先阅读相应的参考文件。
| 主题 | 文件 | 阅读时机 |
|---|---|---|
| 项目结构与设置 | references/core.md | 设置 Django 项目、配置设置、WSGI/ASGI、管理命令 |
| 模型设计 | references/models.md | 创建或修改模型、字段、关系、Meta 选项、管理器、抽象模型/代理模型 |
| ORM 查询 | references/queries.md | 编写查询、修复 N+1 问题、使用 Q/F 对象、聚合、子查询、事务 |
| 迁移 | references/migrations.md | 创建迁移、数据迁移、合并迁移、零停机架构变更 |
| Django Admin | references/admin.md | 配置管理后台、内联模型、自定义操作、字段集、管理后台安全性/性能 |
| 视图 | references/views.md | 编写 FBV 或 CBV、通用视图、混入类、选择 FBV 或 CBV |
| 分页 | references/pagination.md | 为查询集分页、保留筛选条件的页面链接、键集分页、AsyncPaginator |
| URL 路由 | references/urls.md | 配置 URL、命名空间、路径转换器、reverse/reverse_lazy |
| 模板 | references/templates.md | 模板继承、标签、过滤器、自定义模板标签、上下文处理器、安全性 |
| 表单 | references/forms.md | Django 表单、ModelForms、验证、自定义验证器、表单集、文件上传安全性 |
| 消息 | references/messages.md | 表单提交后的闪现消息、SuccessMessageMixin、消息级别与渲染 |
| 身份验证与会话 | references/auth.md | 用户模型、身份验证后端、登录/注销、密码重置、权限、用户组、会话、Cookie |
| 中间件 | references/middleware.md | 中间件顺序、自定义中间件、异常处理、异步中间件 |
| 静态文件与媒体文件 | references/static-media.md | 静态文件/媒体文件配置、collectstatic、WhiteNoise、S3/CDN、文件上传、存储后端 |
| 安全性 | references/security.md | CSRF、XSS、SQL 注入、点击劫持、密码哈希、HTTPS、SECRET_KEY、安全检查 |
| 信号 | references/signals.md | pre/post_save、pre/post_delete、m2m_changed、自定义信号、何时应避免使用信号 |
| 缓存 | references/caching.md | 缓存后端、Redis、按视图/片段/低级别缓存、失效策略 |
| 国际化 | references/i18n.md | i18n 设置、gettext/gettext_lazy、翻译标签、时区支持、区域设置结构 |
| 测试 | references/testing.md | TestCase 类型、Client/RequestFactory、夹具、pytest-django、factory_boy、模拟、覆盖率 |
| Django REST Framework | references/drf.md | 序列化器、视图集、路由器、身份验证、权限、限流、分页、筛选 |
| 后台任务 | references/celery.md | Celery 设置、Django 6.0 原生任务(django.tasks)、任务定义、重试、队列、定期任务、幂等性 |
| 发送电子邮件 | references/email.md | send_mail、HTML 电子邮件、按环境配置后端、批量发送、标头注入 |
| 日志记录 | references/logging.md | LOGGING 配置、内置日志记录器、生产环境中的错误可见性、Sentry、不应记录的内容 |
| 异步 Django | references/async.md | 异步视图、异步 ORM(aget/acreate)、sync_to_async、异步身份验证/会话、何时值得采用异步 |
| 部署与性能 | references/deployment.md | Gunicorn、Nginx、Docker、CI/CD、零停机部署、查询优化、索引、异步视图 |
| Django Channels | references/channels.md | ASGI 设置、WebSocket 消费者、通道层、群组消息传递、WS 身份验证、SSE |
| Django 生态系统 | references/ecosystem.md | DRF、django-filter、allauth、debug toolbar、storages、guardian、import-export、unfold、django-redis、站点地图、内容联合源、重定向 |
| 架构模式 | references/architecture.md | 自定义字段、多数据库、数据库路由器、Jinja2、ORM 内部机制、MTV、服务层、DDD、SOLID |
评论
支持 Markdown