Django GSoC 2026:四个入选项目的技术看点

2026-05-06 13 预计阅读时间:1 分钟
来源:djangoproject.com AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:9 分钟

今年 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 的关系来使用。

当前写法通常是这样的——用 RawSQLExtra 绕路:

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,或者在自己的项目里试用他们产出的新特性。


相关推荐