今年 Django 收到了超过 200 份 GSoC 提案,最终四个项目入选。这些项目不是"锦上添花"的边缘改进——每一个都瞄准了 Django 生态里长期存在的痛点:ORM 对高级 SQL 特性的支持不足、实验性 API 缺乏正式引入机制、测试基础设施老旧、社区工具视觉体验割裂。下面逐个拆解它们要做什么、为什么值得做,以及作为日常 Django 用户可以提前关注什么。
ORM 的表值表达式:让 Subquery 不再绕路
Django ORM 的 Subquery() 目前只能出现在 annotate() 的右侧——你没法把它当成一张表来 JOIN。这在需要用到 PostgreSQL 的 generate_series()、unnest() 等返回集合的函数时尤其尴尬,开发者往往被迫写原生 SQL。
入选项目 "Add support for table-valued expressions in the ORM" 正是要解决这个问题。目标是在 ORM 层面允许你把 Subquery() 或数据库内置的表值函数当作可 JOIN 的关系来使用。
当前写法通常是这样的——用 RawSQL 或 Extra 绕路:
from django.db.models import Count, RawSQL
from myapp.models import Order
# 用 RawSQL 借用 generate_series 生成日期序列再聚合
Order.objects.annotate(
day=RawSQL("generate_series(start_date, end_date, '1 day')", []),
).values('day').annotate(count=Count('id'))
项目完成后,预期可以更自然地表达:
# 假设项目引入了 TableValuedExpression(具体 API 以最终实现为准)
from django.db.models.expressions import TableValuedExpression
date_series = TableValuedExpression.from_function(
'generate_series',
arguments=[start_date, end_date, interval('1 day')],
output_fields=[{'day': models.DateField()}],
)
Order.objects.join(date_series).values('day').annotate(count=Count('id'))
上面的第二段是预期方向的示意,API 名称可能会在开发过程中调整。如果你经常在 Django 里写 extra() 或 RawSQL 来处理这类场景,值得跟踪这个项目的进展。
实验性 API 框架:给 DEP 2 一个落地的机制
Django Enhancement Proposal 2(DEP 2)讨论的是"如何安全地引入实验性 API",但多年来一直停留在提案阶段,没有形成可操作的框架。入选项目 "Implementing an experimental API framework for Django core" 要把它变成现实。
核心思路是 opt-in 模型:新 API 先标记为实验性,开发者需要显式声明才会启用,这样既允许快速迭代,又不会在正式发布前影响已有代码的稳定性。
一个可能的 opt-in 声明方式(示意,具体实现以项目产出为准):
# settings.py
# 声明启用实验性 API
EXPERIMENTAL_APIS = [
'django.db.models.table_valued_expressions',
'django.views.async_streaming',
]
或者在模块级别用装饰器标记:
# django/db/models/table_valued_expressions.py(示意)
from django.utils.experimental import experimental_api
@experimental_api(since='5.2', stable_target='6.0')
class TableValuedExpression(Expression):
...
这对所有写第三方 Django 包的人尤其重要——你可以在自己的包里引用实验性 API,但必须处理它未来可能变更的风险。建议关注项目最终选择的 opt-in 语法,它很可能成为后续 Django 新特性的标准引入路径。
从 Selenium 迁移到 Playwright:测试基础设施换代
Django 的浏览器集成测试目前跑在 Selenium 上。Selenium 的问题不少:启动慢、调试体验差、对现代浏览器特性的支持滞后。入选项目 "Switch to Playwright tests for integration testing" 要把这套测试迁移到 Playwright。
Playwright 的优势很具体:自动等待、内置网络拦截、跨浏览器一致性更好、trace viewer 让失败用例可以回放。对 Django 项目本身来说,迁移意味着 CI 跑得更快、贡献者调试更容易。
如果你现在也在用 Selenium 做 Django 项目的端到端测试,可以提前试水 Playwright:
# 安装 Playwright
pip install playwright
playwright install
# 用 pytest-playwright 跑一个简单测试
pip install pytest-playwright
# tests/test_login.py
from playwright.sync_api import Page, expect
def test_admin_login(page: Page, live_server):
page.goto(f"{live_server.url}/admin/login/")
page.fill("[name=username]", "admin")
page.fill("[name=password]", "secret")
page.click("[type=submit]")
expect(page).to_have_url_regex(r"/admin/$")
注意:live_server fixture 来自 django.contrib.staticfiles.testing.StaticLiveServerTestCase,在 pytest-django 里需要额外配置。上面的示例假设你已经搭好了 pytest-django 环境。Playwright 的 page fixture 由 pytest-playwright 自动注入。
迁移不会一夜完成——Django 的 Selenium 测试用例数量不少,项目会逐步替换。但方向已经明确,新写的集成测试建议直接用 Playwright。
Issue Tracker 暗色模式与视觉统一
Django 的 issue tracker(基于 Codebase)和主站 django-project.com 的视觉风格长期不一致,而且不支持暗色模式。入选项目 "Unified dark mode and UI consistency for Django's issue tracker" 要把 tracker 的外观拉齐到主站,并加入暗色模式。
这看起来是"前端美化",但实际影响不小:开源项目的 issue tracker 是社区协作的主战场,视觉一致性直接影响新贡献者的第一印象。暗色模式也不是纯审美——长时间盯屏幕跟踪 bug 的人,暗色模式是健康需求。
如果你维护自己的 Django 项目文档站点或 issue tracker,现在就可以用 CSS 变量做暗色模式准备:
/* 基础暗色模式 CSS 变量 */
:root {
--bg-primary: #ffffff;
--text-primary: #1a1a1a;
--accent: #0c4b33; /* Django 绿 */
}
@media (prefers-color-scheme: dark) {
:root {
--bg-primary: #1a1a1a;
--text-primary: #e0e0e0;
--accent: #44b78b;
}
}
body {
background-color: var(--bg-primary);
color: var(--text-primary);
}
关键点:用 prefers-color-scheme 媒体查询尊重用户系统偏好,同时用 CSS 变量集中管理颜色,后续加手动切换开关时只需改变量值。
落选不是终点
200 多份提案里只选了 4 个,淘汰率很高。Django 基金会明确说了:落选不代表提案质量差,选择标准包括与项目目标的契合度、时间可行性、过往贡献、提案清晰度等多个维度。因为志愿者团队规模有限,无法提供逐个反馈。
如果你今年落选了,或者打算明年申请,有几件事现在就可以做:
- 持续贡献:在 GitHub 上处理 Django 的 good-first-issue,让社区看到你的提交记录。
- 提前写提案草稿:GSoC 申请期开始前,在 Django 论坛或 Discord 上讨论你的想法,收集反馈。
- 关注 DEP 列表:很多入选项目的源头是已有的 DEP,了解哪些 DEP 还没落地,能帮你找到方向。
# 快速查看当前 Django 仓库里的 good-first-issue
gh issue list --repo django/django --label "good first issue" --limit 20
四个项目的社区磨合期已经开始,代码产出会在未来几个月陆续出现。如果你对某个项目特别感兴趣,最直接的支持方式是:在邮件列表或 Discord 里给贡献者反馈,review 他们的 PR,或者在自己的项目里试用他们产出的新特性。