---
title: "提交贡献"
version: 5.1
locale: zh-hans
source: https://docs.djangoproject.com/zh-hans/5.1/internals/contributing/writing-code/submitting-patches/
canonical: https://djangodocs.dev/zh-hans/5.1/internals/contributing/writing-code/submitting-patches/
---
# 提交贡献

我们总是感激对 Django 代码的贡献。事实上，带有相关贡献的错误报告将比没有解决方案的错误报告修复得 *快得多*。

## 错字修复和琐碎的文档更改

如果您正在修复一个非常微不足道的问题，例如更改文档中的一个单词，推荐的方法是使用 GitHub 提交拉取请求，而无需使用 Trac 工单。

有关如何使用拉取请求的更多详细信息，请参见 [使用 Git 和 GitHub 工作](/zh-hans/5.1/internals/contributing/writing-code/working-with-git/) 。

## “发布”工单

在一个全球有数百个贡献者的开源项目中，有效地管理沟通以避免重复工作并尽可能提高贡献者的效率是非常重要的。

因此，我们的政策是供贡献者“发布”工单，以便让其他开发人员知道正在处理特定的错误或功能。

如果您确定了要做出的贡献并且有能力解决（通过编程能力，Django内核知识水平和时间可用性来衡量），请按照以下步骤进行发表：

- [使用您的 GitHub 帐户登录](https://www.djangoproject.com/accounts/register/) 或在我们的工单系统中 [创建一个帐户](https://code.djangoproject.com/github/login)。如果您有帐户但忘记了密码，可以使用 [密码重置页面](https://www.djangoproject.com/accounts/password/reset/) 进行重置。
- 如果尚无此问题的工单，请在我们的 [ticket tracker](https://code.djangoproject.com/) 工单追踪系统中创建一个。
- 如果此问题已有相关工单，请确保没有其他人认领。要做到这一点，查看工单的 " Owned by "（负责人）部分。如果它被分配给了 " nobody "（无人认领），那么它可以被认领。否则，可能已经有其他人正在处理此工单。您可以选择另一个错误或功能来处理，或者联系负责此工单的开发人员提供帮助。如果一个工单在数周或数月内没有任何活动，那么将其重新分配给自己可能是安全的。
- 登录你的账户，如果还没有登录，点击工单页面左上角的“GitHub 登录”或“DjangoProject 登录”。登录后，你可以点击页面底部的“修改工单”按钮。
- 点击“操作”部分中的“分配”单选按钮来认领工单。默认情况下，你的用户名将填入文本框。
- 最后点击底部的“提交更改”按钮保存。

> **Note**
>
> Django 软件基金会要求任何对 Django 做出非微小更改的贡献者签署并提交 [贡献者许可协议](https://www.djangoproject.com/foundation/cla/)，这确保 Django 软件基金会对所有贡献拥有明确的许可，从而为所有用户提供明确的许可。

### 工单发表者的责任

发布工单后，您有责任以合理及时的方式处理该工单。 如果您没有时间来处理它，请先取消发布或不发布它！

如果一两周内没有任何关于特定已发布工单的进展迹象，则另一位开发人员可能会要求您放弃该发布了的工单，以使其不再被垄断，而其他人也可以发布。

如果您已发布工单，并且要花很长时间（几天或几周）编写代码，请通过在工单上发布评论来使每个人都保持最新状态。如果您不提供定期更新，并且不响应进度报告的请求，则您对工单的要求可能会被撤消。

与往常一样，多交流好过少交流！

### 应该发布哪类工单？

在某些情况下，执行认领工单的步骤可能过于繁琐。

对于小更改，例如文档中的拼写错误或只需几分钟修复的小错误，你不需要经历认领工单的繁琐过程。直接提交你的更改即可完成！

无论是否有人认领工单，如果你碰巧已经准备好更改，*总是* 可以接受将提案链接到工单。

## 贡献风格

确保您所做的任何贡献至少满足以下要求：

- 修复问题或添加功能所需的代码是解决方案的重要组成部分，但不是唯一的部分。一个好的修复还应包括一个 [回归测试](/zh-hans/5.1/internals/contributing/writing-code/unit-tests/) 来验证已修复的行为并防止问题再次出现。此外，如果某些工单与你编写的代码相关，请在测试的注释中提及工单编号，以便在你的补丁提交后可以轻松追溯相关讨论，并且工单被关闭。
- 如果代码添加了新功能，或修改了现有功能的行为，更改还应包含文档。

当你认为你的工作已经准备好接受审查时，发送 [GitHub 拉取请求](/zh-hans/5.1/internals/contributing/writing-code/working-with-git/)。如果由于某种原因无法发送拉取请求，你也可以在 Trac 中使用补丁。使用这种方式时，请遵循以下指南。

- 请以 `git diff` 命令返回的格式提交补丁。
- 使用“附加文件”按钮将补丁附加到 [ticket tracker](https://code.djangoproject.com/) 工单跟踪系统中的工单上。 除非是单行补丁，否则请 *不要* 将补丁放入工单描述或注释中。
- 用扩展名 `.diff` 命名补丁文件； 这将使工单跟踪系统应用正确的语法突出显示，这非常有帮助。

无论您以何种方式提交工作成果，请按照以下步骤操作。

- 确保你的代码满足我们的 [贡献清单](#patch-review-checklist) 中的要求。
- 勾选工单上的 "Has patch" 复选框，并确保 "Needs documentation"、"Needs tests" 和 "Patch needs improvement" 复选框没有被勾选。这将使工单显示在 [Development dashboard](https://dashboard.djangoproject.com/) 的 "Patches needing review" 队列中。

## 需要社区反馈的贡献

当补丁引入新的 Django 功能并做出某种设计决策时，需要更广泛的社区讨论。如果方法涉及 [弃用](#deprecating-a-feature) 或引入破坏性更改，这一点尤为重要。

以下是获得社区反馈的不同方法。

### The Django Forum

You can propose a change on the [Django Forum](https://forum.djangoproject.com/). You should explain the need
for the change, go into details of the approach and discuss alternatives.

请在贡献中包含此类讨论的链接。

### 第三方包

Django 不接受实验性功能。所有功能必须遵循我们的 [弃用政策](/zh-hans/5.1/internals/release-process/#internal-release-deprecation-policy)。因此，Django 可能需要数月或数年的时间来迭代 API 设计。

如果你需要用户对公共接口的反馈，最好先创建一个第三方包。你可以更快地迭代公共 API，同时验证功能的需求。

Once this package becomes stable and there are clear benefits of incorporating
aspects into Django core, starting a discussion on the [Django Forum](https://forum.djangoproject.com/) would be
the next step.

### Django 增强提案 (DEP)

类似于 Python 的 PEP，Django 有 [Django 增强提案](https://github.com/django/deps) 或 DEP。DEP 是一份设计文档，向 Django 社区提供信息，或描述 Django 的新功能或流程。它们提供了功能的技术规范及其理由。DEP 也是提议和收集社区对主要新功能意见的主要机制。

Before considering writing a DEP, it is recommended to first open a discussion
on the [Django Forum](https://forum.djangoproject.com/). This allows the community to provide feedback and helps
refine the proposal. Once the DEP is ready the [Steering Council](/zh-hans/5.1/internals/organization/#steering-council) votes on whether to accept it.

一些已被批准并完全实施的 DEP 示例：

- [DEP 181: ORM 表达式](https://github.com/django/deps/blob/main/final/0181-orm-expressions.rst)
- [DEP 182: 多模板引擎](https://github.com/django/deps/blob/main/final/0182-multiple-template-engines.rst)
- [DEP 201: 简化路由语法](https://github.com/django/deps/blob/main/final/0201-simplified-routing-syntax.rst)

## 弃用一个功能

Django 中的代码可能被弃用的原因有几个：

- 如果一个功能在与向后兼容性不兼容的方式下进行了改进或修改，旧的功能或行为将被弃用。
- 有时，Django 会包含一个 Python 库的后移版本，而该库在 Django 当前支持的 Python 版本中不包含。当 Django 不再需要支持不包含该库的旧版本 Python 时，该库将在 Django 中被弃用。

正如 [弃用政策](/zh-hans/5.1/internals/release-process/#internal-release-deprecation-policy) 所描述的那样，第一个弃用某项功能的 Django 版本（`A.B`）在调用被弃用功能时应该引发一个 `RemovedInDjangoXXWarning` 警告（其中 XX 是将要删除该功能的 Django 版本）。假设我们有良好的测试覆盖率，在启用警告的情况下，这些警告将在 [运行测试套件](/zh-hans/5.1/internals/contributing/writing-code/unit-tests/#running-unit-tests) 时转换为错误：`python -Wa runtests.py`。因此，在添加 `RemovedInDjangoXXWarning` 时，您需要消除或消除运行测试时生成的任何警告。

第一步是通过 Django 自身去除对被弃用行为的使用。接下来，您可以使用 `ignore_warnings` 装饰器来消除测试中实际测试被弃用行为的警告，可以在测试或类级别使用它：

1. 在一个特定的测试中：

   ```
   from django.test import ignore_warnings
   from django.utils.deprecation import RemovedInDjangoXXWarning

   @ignore_warnings(category=RemovedInDjangoXXWarning)
   def test_foo(self): ...
   ```
2. 对于整个测试用例：

   ```
   from django.test import ignore_warnings
   from django.utils.deprecation import RemovedInDjangoXXWarning

   @ignore_warnings(category=RemovedInDjangoXXWarning)
   class MyDeprecatedTests(unittest.TestCase): ...
   ```

您还应该为弃用警告添加一个测试：

```
from django.utils.deprecation import RemovedInDjangoXXWarning

def test_foo_deprecation_warning(self):
    msg = "Expected deprecation message"
    with self.assertWarnsMessage(RemovedInDjangoXXWarning, msg) as ctx:
        # invoke deprecated behavior
        ...
    self.assertEqual(ctx.filename, __file__)
```

重要的是在没有警告引用但在弃用结束时需要更改或删除的代码上方包含一个 `RemovedInDjangoXXWarning` 注释。这可能包括已添加以保持先前行为的钩子，或在弃用结束时不再需要或未使用的独立项目。例如：

```
import warnings
from django.utils.deprecation import RemovedInDjangoXXWarning

# RemovedInDjangoXXWarning.
def old_private_helper():
    # Helper function that is only used in foo().
    pass

def foo():
    warnings.warn(
        "foo() is deprecated.",
        category=RemovedInDjangoXXWarning,
        stacklevel=2,
    )
    old_private_helper()
    ...
```

最后，还有一些更新需要进行，以更新 Django 的文档：

1. 如果现有功能已经在文档中记录，请使用 `.. deprecated:: A.B` 注解在文档中标记它为已弃用。如果适用，包括一个简短的描述和有关升级路径的说明。
2. 将已弃用行为的描述以及升级路径（如果适用）添加到当前版本的发行说明（`docs/releases/A.B.txt`）中，放在 "Features deprecated in A.B" 标题下。
3. 在适当的版本下，将一个条目添加到弃用时间表（`docs/internals/deprecation.txt`）中，描述将要被移除的代码。

一旦完成了这些步骤，你就完成了弃用过程。在每个 [特性发布](/zh-hans/5.1/internals/release-process/#term-Feature-release) 中，与新版本匹配的所有 `RemovedInDjangoXXWarning` 都会被移除。

## JavaScript 贡献

有关 JavaScript 贡献的信息，请参阅 [JavaScript 补丁](/zh-hans/5.1/internals/contributing/writing-code/javascript/#javascript-patches) 文档。

## 优化补丁

旨在提供性能改进的补丁应提供基准测试，显示补丁前后的影响，并分享供审查者复现的命令。

### `django-asv` 基准测试

[django-asv](https://github.com/django/django-asv/) 监控 Django 代码的性能随时间的变化。这些基准测试可以通过在拉取请求上标记 `benchmark` 来运行。强烈鼓励添加这些基准测试。

## 贡献清单

使用此清单审查拉取请求。如果你正在审查不是你自己提交的拉取请求，并且它满足以下所有标准，请将相应的 Trac 工单的“分类阶段”设置为“准备检入”。如果你在拉取请求上留下了改进意见，请根据审查结果在 Trac 工单上勾选适当的标志：“补丁需要改进”、“需要文档”和/或“需要测试”。根据时间和兴趣，合并者会对“准备检入”的工单进行最终审查，并提交更改，或者如果需要进一步工作，则将其退回“已接受”。如果你想成为合并者，彻底审查贡献是赢得信任的好方法。

正在寻找要审查的补丁？查看 [Django 开发仪表板](https://dashboard.djangoproject.com/) 的“需要审查的补丁”部分。

希望你的拉取请求被审查？确保工单上的 Trac 标志已设置，以便工单出现在该队列中。

### 文档

- 文档是否能够在没有任何错误的情况下构建（从 `docs` 目录执行 `make html`，或者在 Windows 上执行 `make.bat html`）？
- 文档是否遵循 [编写文档](/zh-hans/5.1/internals/contributing/writing-documentation/) 中的写作风格指南？
- 是否存在任何 [拼写错误](/zh-hans/5.1/internals/contributing/writing-documentation/#documentation-spelling-check)？

### 错误

- 是否有适当的回归测试（在应用修复之前，测试应该失败）？
- 如果是一个符合 Django 稳定版本的 [可回退](/zh-hans/5.1/internals/release-process/#supported-versions-policy) 的 bug，是否在 `docs/releases/A.B.C.txt` 中有一份发行说明？只会应用到主分支的 bug 修复不需要发行说明。

### 新功能

- 是否有测试来 "运行" 所有新代码？
- 是否在 `docs/releases/A.B.txt` 中有一份发行说明？
- 是否为该功能提供了文档，并且文档是否适当地使用了 `.. versionadded:: A.B` 或 `.. versionchanged:: A.B` 进行了 [注释](/zh-hans/5.1/internals/contributing/writing-documentation/#documenting-new-features) ？

### 弃用一个功能

请参阅 [弃用一个功能](#deprecating-a-feature) 指南。

### 所有代码更改

- Does the [coding style](/zh-hans/5.1/internals/contributing/writing-code/coding-style/) conform to our
  guidelines? Are there any  `black`, `blacken-docs`, `flake8`,
  `isort`, or `zizmor` errors? You can install the [pre-commit](/zh-hans/5.1/internals/contributing/writing-code/coding-style/#coding-style-pre-commit) hooks to automatically catch these errors.
- 如果更改在任何方面不向后兼容，是否在发行说明（`docs/releases/A.B.txt`）中有说明？
- Django 的测试套件是否通过？

### 所有工单

- 拉取请求是否是一个合并的提交，其提交消息符合我们的 [提交消息格式](/zh-hans/5.1/internals/contributing/committing-code/#committing-guidelines)？
- 您是否是补丁的作者并且是新的贡献者？请将自己添加到 [AUTHORS](https://github.com/django/django/blob/stable/5.1.x/AUTHORS) 文件并提交 [Contributor License Agreement](https://www.djangoproject.com/foundation/cla/)。
