{"title":"编码风格","version":"5.0","locale":"zh-hans","docname":"internals/contributing/writing-code/coding-style","url":"/zh-hans/5.0/internals/contributing/writing-code/coding-style/","canonical":"https://djangodocs.dev/zh-hans/5.0/internals/contributing/writing-code/coding-style/","summary":"当编写Django代码时，请遵从这些编码标准。 预提交检查 Link to this heading # pre-commit 是一个用于管理预提交钩子的框架。这些钩子有助于在提交代码进行审查之前识别简单的问题。通过在代码审查之前检查这些问题，它可以让审查人员集中精力在更改本身上，还可以帮助减少 CI 运行的次数。…","html":"<h1>编码风格<a class=\"heading-anchor\" href=\"#coding-style\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>当编写Django代码时，请遵从这些编码标准。</p>\n<section id=\"pre-commit-checks\">\n<span id=\"coding-style-pre-commit\"></span><h2>预提交检查<a class=\"heading-anchor\" href=\"#pre-commit-checks\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p><a class=\"reference external\" href=\"https://pre-commit.com\">pre-commit</a> 是一个用于管理预提交钩子的框架。这些钩子有助于在提交代码进行审查之前识别简单的问题。通过在代码审查之前检查这些问题，它可以让审查人员集中精力在更改本身上，还可以帮助减少 CI 运行的次数。</p>\n<p>要使用这个工具，首先安装 <code class=\"docutils literal notranslate\"><span class=\"pre\">pre-commit</span></code>，然后安装 Git 钩子：</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-0-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>python<span class=\"w\"> </span>-m<span class=\"w\"> </span>pip<span class=\"w\"> </span>install<span class=\"w\"> </span>pre-commit\n<span class=\"gp\">$ </span>pre-commit<span class=\"w\"> </span>install\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-0-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> py -m pip install pre-commit\n<span class=\"gp\">...\\&gt;</span> pre-commit install\n</code></pre></div></div></div>\n<p>在第一次提交时，<code class=\"docutils literal notranslate\"><span class=\"pre\">pre-commit</span></code> 将安装钩子，这些钩子会安装在它们自己的环境中，并且在第一次运行时需要一点时间来安装。后续的检查将会快得多。如果发现错误，将显示相应的错误消息。如果错误与 <code class=\"docutils literal notranslate\"><span class=\"pre\">black</span></code> 或 <code class=\"docutils literal notranslate\"><span class=\"pre\">isort</span></code> 有关，那么工具会为你修复它们。请查看更改并在满意后重新暂存以进行提交。</p>\n</section>\n<section id=\"python-style\">\n<span id=\"coding-style-python\"></span><h2>Python 编码风格<a class=\"heading-anchor\" href=\"#python-style\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<ul>\n<li><p>所有文件应该使用 <a class=\"reference external\" href=\"https://black.readthedocs.io/en/stable/\">black</a> 自动格式化工具进行格式化。如果已配置，这将由 <code class=\"docutils literal notranslate\"><span class=\"pre\">pre-commit</span></code> 运行。</p></li>\n<li><p>项目仓库包括一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">.editorconfig</span></code> 文件。我们建议使用支持 <a class=\"reference external\" href=\"https://editorconfig.org/\">EditorConfig</a> 的文本编辑器，以避免缩进和空白字符问题。Python 文件使用 4 个空格缩进，而 HTML 文件使用2个空格。</p></li>\n<li><p>除非另有约定的情况下，否则遵从 PEP8 编码规范。</p>\n<p>使用 <a class=\"extlink-pypi reference external\" href=\"https://pypi.org/project/flake8/\">flake8</a> 来检查这个方面的问题。请注意，我们的 <code class=\"docutils literal notranslate\"><span class=\"pre\">setup.cfg</span></code> 文件包含一些被排除的文件（我们不关心清理的已弃用模块和一些 Django 供应的第三方代码），以及一些被排除的错误，我们不认为它们是严重的违规。请记住，<span class=\"target\" id=\"index-10\"></span><a class=\"pep reference external\" href=\"https://peps.python.org/pep-0008/\"><strong>PEP 8</strong></a> 只是一个指南，所以尊重周围代码的风格是主要目标。</p>\n<p>对于 <span class=\"target\" id=\"index-11\"></span><a class=\"pep reference external\" href=\"https://peps.python.org/pep-0008/\"><strong>PEP 8</strong></a> 的一个例外是我们对行长度的规定。如果限制代码行的长度为 79 个字符会使代码看起来显著难看或难以阅读，那么不要这样做。我们允许最多 88 个字符，因为这是 <code class=\"docutils literal notranslate\"><span class=\"pre\">black</span></code> 使用的行长度。当你运行 <code class=\"docutils literal notranslate\"><span class=\"pre\">flake8</span></code> 时，这个检查会包含在内。然而，文档、注释和文档字符串应该在 79 个字符处换行，即使 <span class=\"target\" id=\"index-12\"></span><a class=\"pep reference external\" href=\"https://peps.python.org/pep-0008/\"><strong>PEP 8</strong></a> 建议是 72 个字符。</p>\n</li>\n<li><p>字符串变量插值可以使用 <a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#old-string-formatting\" title=\"(in Python v3.14)\"><span class=\"xref std std-ref\">%-formatting</span></a>、<a class=\"reference external\" href=\"https://docs.python.org/3/reference/lexical_analysis.html#f-strings\" title=\"(in Python v3.14)\"><span class=\"xref std std-ref\">f-strings</span></a> 或 <a class=\"reference external\" href=\"https://docs.python.org/3/library/stdtypes.html#str.format\" title=\"(in Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">str.format()</span></code></a>，以提高代码的可读性为目标。</p>\n<p>关于可读性的最终判断留给合并者自行决定。作为指南，f-strings 应仅使用普通的变量和属性访问，在更复杂的情况下，应先进行本地变量赋值。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># Allowed</span>\n<span class=\"sa\">f</span><span class=\"s2\">&quot;hello </span><span class=\"si\">{</span><span class=\"n\">user</span><span class=\"si\">}</span><span class=\"s2\">&quot;</span>\n<span class=\"sa\">f</span><span class=\"s2\">&quot;hello </span><span class=\"si\">{</span><span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"si\">}</span><span class=\"s2\">&quot;</span>\n<span class=\"sa\">f</span><span class=\"s2\">&quot;hello </span><span class=\"si\">{</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"si\">}</span><span class=\"s2\">&quot;</span>\n\n<span class=\"c1\"># Disallowed</span>\n<span class=\"sa\">f</span><span class=\"s2\">&quot;hello </span><span class=\"si\">{</span><span class=\"n\">get_user</span><span class=\"p\">()</span><span class=\"si\">}</span><span class=\"s2\">&quot;</span>\n<span class=\"sa\">f</span><span class=\"s2\">&quot;you are </span><span class=\"si\">{</span><span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">age</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"w\"> </span><span class=\"mf\">365.25</span><span class=\"si\">}</span><span class=\"s2\"> days old&quot;</span>\n\n<span class=\"c1\"># Allowed with local variable assignment</span>\n<span class=\"n\">user</span> <span class=\"o\">=</span> <span class=\"n\">get_user</span><span class=\"p\">()</span>\n<span class=\"sa\">f</span><span class=\"s2\">&quot;hello </span><span class=\"si\">{</span><span class=\"n\">user</span><span class=\"si\">}</span><span class=\"s2\">&quot;</span>\n<span class=\"n\">user_days_old</span> <span class=\"o\">=</span> <span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">age</span> <span class=\"o\">*</span> <span class=\"mf\">365.25</span>\n<span class=\"sa\">f</span><span class=\"s2\">&quot;you are </span><span class=\"si\">{</span><span class=\"n\">user_days_old</span><span class=\"si\">}</span><span class=\"s2\"> days old&quot;</span>\n</code></pre></div>\n<p>不应该在可能需要翻译的任何字符串，包括错误和日志消息中使用 f-strings。一般来说，<code class=\"docutils literal notranslate\"><span class=\"pre\">format()</span></code> 更加冗长，因此更倾向于使用其他格式化方法。</p>\n<p>不要浪费时间对现有代码进行无关的重构来调整格式化方法。</p>\n</li>\n<li><p>在注释中避免使用 &quot; we &quot;，例如使用 &quot; Loop over &quot; 而不是 &quot; We loop over &quot;。</p></li>\n<li><p>在给变量，函数和方法命名时候使用下划线而不是小驼峰 (例如：  poll.get_unique_voters(), not poll.getUniqueVoters() )。</p></li>\n<li><p>类名使用“大驼峰命名法”（或者是用在能返回类的工厂函数上面）。</p></li>\n<li><p>对于文档字符串，遵从现有文档字符串风格和 PEP257 规范。</p></li>\n<li><p>在测试中，使用 <a class=\"reference internal\" href=\"/zh-hans/5.0/topics/testing/tools/#django.test.SimpleTestCase.assertRaisesMessage\" title=\"django.test.SimpleTestCase.assertRaisesMessage\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertRaisesMessage()</span></code></a> 和 <a class=\"reference internal\" href=\"/zh-hans/5.0/topics/testing/tools/#django.test.SimpleTestCase.assertWarnsMessage\" title=\"django.test.SimpleTestCase.assertWarnsMessage\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertWarnsMessage()</span></code></a>，而不是 <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertRaises\" title=\"(in Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertRaises()</span></code></a> 和 <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertWarns\" title=\"(in Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertWarns()</span></code></a>，这样可以检查异常或警告消息。只有在需要正则表达式匹配时才使用 <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertRaisesRegex\" title=\"(in Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertRaisesRegex()</span></code></a> 和 <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertWarnsRegex\" title=\"(in Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertWarnsRegex()</span></code></a>。</p>\n<p>在测试布尔值时，使用 <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertIs\" title=\"(in Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertIs(…,</span> <span class=\"pre\">True/False)</span></code></a>，而不是 <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertTrue\" title=\"(in Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertTrue()</span></code></a> 和 <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertFalse\" title=\"(in Python v3.14)\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">assertFalse()</span></code></a>，这样可以检查实际的布尔值，而不是表达式的真值。</p>\n</li>\n<li><p>在测试文档字符串中，说明每个测试展示的预期行为。不要包含像 &quot; Tests that &quot; 或 &quot; Ensures that &quot; 这样的前言。</p>\n<p>保留工单引用用于描述复杂问题，其中工单包含无法轻易在文档字符串或注释中描述的额外细节。在句子末尾包含工单号，如下所示：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_foo</span><span class=\"p\">():</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">    A test docstring looks like this (#123456).</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n</li>\n</ul>\n</section>\n<section id=\"imports\">\n<span id=\"coding-style-imports\"></span><h2>导入<a class=\"heading-anchor\" href=\"#imports\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<ul>\n<li><p>使用 <a class=\"extlink-pypi reference external\" href=\"https://pypi.org/project/isort/\">isort</a> 来自动按照以下指南进行导入排序。</p>\n<p>快速入门：</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-1-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>python<span class=\"w\"> </span>-m<span class=\"w\"> </span>pip<span class=\"w\"> </span>install<span class=\"w\"> </span><span class=\"s2\">&quot;isort &gt;= 5.1.0&quot;</span>\n<span class=\"gp\">$ </span>isort<span class=\"w\"> </span>.\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-1-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> py -m pip install <span class=\"s2\">&quot;isort &gt;= 5.1.0&quot;</span>\n<span class=\"gp\">...\\&gt;</span> isort .\n</code></pre></div></div></div>\n<p>这将从你的当前目录递归运行 <code class=\"docutils literal notranslate\"><span class=\"pre\">isort</span></code> ，修改所有不符合指引的文件，如果你不需要排序（例如：避免循环导入）请在你的导入里面像这样加上注释：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">module</span>  <span class=\"c1\"># isort:skip</span>\n</code></pre></div>\n</li>\n<li><p>把导入这样进行分组：future库，python标准库，第三方库， 其他的Django组件，本地Django组件，try/excepts块。按照字母顺序对每个分组进行排序，按照完整的模块名称。在每个分组里面把import module句子放在 from module importobjects句子前面。对于其他Django组件使用绝对导入，对本地Django组件使用相对导入。</p></li>\n<li><p>在每一行上，按字母顺序排列项目，将大写字母的项目放在小写字母的项目之前分组。</p></li>\n<li><p>使用括号和4个连续空格构成的缩进去打破长行，在最后一个导入之后写一个逗号，把右括号放在单独一行。</p>\n<p>在最后一个导入和任何代码块之间留出一个空行，在第一个函数或类前面留出两个空行。</p>\n<p>例如（注释仅作为解释用途）：</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\"><code class=\"docutils literal notranslate\"><span class=\"pre\">django/contrib/admin/example.py</span></code></figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"c1\"># future</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">__future__</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">unicode_literals</span>\n\n<span class=\"c1\"># standard library</span>\n<span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">json</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">itertools</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">chain</span>\n\n<span class=\"c1\"># third-party</span>\n<span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">bcrypt</span>\n\n<span class=\"c1\"># Django</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Http404</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http.response</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"p\">(</span>\n    <span class=\"n\">Http404</span><span class=\"p\">,</span>\n    <span class=\"n\">HttpResponse</span><span class=\"p\">,</span>\n    <span class=\"n\">HttpResponseNotAllowed</span><span class=\"p\">,</span>\n    <span class=\"n\">StreamingHttpResponse</span><span class=\"p\">,</span>\n    <span class=\"n\">cookie</span><span class=\"p\">,</span>\n<span class=\"p\">)</span>\n\n<span class=\"c1\"># local Django</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">LogEntry</span>\n\n<span class=\"c1\"># try/except</span>\n<span class=\"k\">try</span><span class=\"p\">:</span>\n    <span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">yaml</span>\n<span class=\"k\">except</span> <span class=\"ne\">ImportError</span><span class=\"p\">:</span>\n    <span class=\"n\">yaml</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n\n<span class=\"n\">CONSTANT</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;foo&quot;</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Example</span><span class=\"p\">:</span> <span class=\"o\">...</span>\n</code></pre></figure>\n</li>\n<li><p>在可用时，请使用方便的导入方式。例如，这样做：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">View</span>\n</code></pre></div>\n<p>替换成：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic.base</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">View</span>\n</code></pre></div>\n</li>\n</ul>\n</section>\n<section id=\"template-style\">\n<h2>模版风格<a class=\"heading-anchor\" href=\"#template-style\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<ul>\n<li><p>在Django模板代码中，在大括号和标签内容之间放置一个（只有一个）空格。</p>\n<p>这样做：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{{</span> <span class=\"nv\">foo</span> <span class=\"cp\">}}</span>\n</code></pre></div>\n<p>不要这样做：</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{{</span><span class=\"nv\">foo</span><span class=\"cp\">}}</span>\n</code></pre></div>\n</li>\n</ul>\n</section>\n<section id=\"view-style\">\n<h2>视图风格<a class=\"heading-anchor\" href=\"#view-style\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<ul>\n<li><p>在Django的视图中，第一个参数应该总是 <code class=\"docutils literal notranslate\"><span class=\"pre\">request</span></code> 。</p>\n<p>这样做：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">foo</span><span class=\"p\">):</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>别这样做：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">req</span><span class=\"p\">,</span> <span class=\"n\">foo</span><span class=\"p\">):</span> <span class=\"o\">...</span>\n</code></pre></div>\n</li>\n</ul>\n</section>\n<section id=\"model-style\">\n<h2>模型风格<a class=\"heading-anchor\" href=\"#model-style\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<ul>\n<li><p>字段名称应当全部使用小写，使用下划线替代驼峰命名。</p>\n<p>这样做：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Person</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">first_name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">20</span><span class=\"p\">)</span>\n    <span class=\"n\">last_name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">40</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>别这样做：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Person</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">FirstName</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">20</span><span class=\"p\">)</span>\n    <span class=\"n\">Last_Name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">40</span><span class=\"p\">)</span>\n</code></pre></div>\n</li>\n<li><p> <code class=\"docutils literal notranslate\"><span class=\"pre\">class</span> <span class=\"pre\">Meta</span></code> 类应该位于定义字段之后，用一个空行分割字段定义和类定义。</p>\n<p>这样做：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Person</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">first_name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">20</span><span class=\"p\">)</span>\n    <span class=\"n\">last_name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">40</span><span class=\"p\">)</span>\n\n    <span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        <span class=\"n\">verbose_name_plural</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;people&quot;</span>\n</code></pre></div>\n<p>别这样做：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Person</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        <span class=\"n\">verbose_name_plural</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;people&quot;</span>\n\n    <span class=\"n\">first_name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">20</span><span class=\"p\">)</span>\n    <span class=\"n\">last_name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">40</span><span class=\"p\">)</span>\n</code></pre></div>\n</li>\n<li><p>模型内的类核方法的定义应该遵循以下顺序（不是所有项都是必须的）：</p>\n<ul class=\"simple\">\n<li><p>所有数据库字段</p></li>\n<li><p>自定义管理器属性</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">Meta</span> <span class=\"pre\">类</span></code></p></li>\n<li><p>`` __str__() 方法``</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span> <span class=\"pre\">方法</span></code></p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">get_absolute_url()</span> <span class=\"pre\">方法</span></code></p></li>\n<li><p>其他自定义方法</p></li>\n</ul>\n</li>\n<li><p>如果为给定的模型字段定义了 <code class=\"docutils literal notranslate\"><span class=\"pre\">choices</span></code>，请将每个选择定义为一个映射，使用全大写名称作为模型上的类属性。示例：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyModel</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">DIRECTION_UP</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;U&quot;</span>\n    <span class=\"n\">DIRECTION_DOWN</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;D&quot;</span>\n    <span class=\"n\">DIRECTION_CHOICES</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n        <span class=\"n\">DIRECTION_UP</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Up&quot;</span><span class=\"p\">,</span>\n        <span class=\"n\">DIRECTION_DOWN</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Down&quot;</span><span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n</code></pre></div>\n<p>或者，考虑使用 <a class=\"reference internal\" href=\"/zh-hans/5.0/ref/models/fields/#field-choices-enum-types\"><span class=\"std std-ref\">枚举类型</span></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyModel</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Direction</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">TextChoices</span><span class=\"p\">):</span>\n        <span class=\"n\">UP</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;U&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Up&quot;</span>\n        <span class=\"n\">DOWN</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;D&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Down&quot;</span>\n</code></pre></div>\n</li>\n</ul>\n</section>\n<section id=\"use-of-django-conf-settings\">\n<h2><code class=\"docutils literal notranslate\"><span class=\"pre\">django.conf.settings</span></code> 配置的使用<a class=\"heading-anchor\" href=\"#use-of-django-conf-settings\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>通常，模块不应使用存储在顶层的配置 <code class=\"docutils literal notranslate\"><span class=\"pre\">django.conf.settings</span></code> 配置（即在导入模块时进行评估）。 对此的解释如下：</p>\n<p>手动配置设置（即不依赖于 <span class=\"target\" id=\"index-13\"></span><a class=\"reference internal\" href=\"/zh-hans/5.0/topics/settings/#envvar-DJANGO_SETTINGS_MODULE\"><code class=\"xref std std-envvar docutils literal notranslate\"><span class=\"pre\">DJANGO_SETTINGS_MODULE</span></code></a> 环境变量）是允许的，并且可以按以下方式进行：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.conf</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">settings</span>\n\n<span class=\"n\">settings</span><span class=\"o\">.</span><span class=\"n\">configure</span><span class=\"p\">({},</span> <span class=\"n\">SOME_SETTING</span><span class=\"o\">=</span><span class=\"s2\">&quot;foo&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>但是，如果在配置 <code class=\"docutils literal notranslate\"><span class=\"pre\">settings.configure</span></code> 行配置之前访问了任何设置，则此操作将无效。（在内部，<code class=\"docutils literal notranslate\"><span class=\"pre\">settings</span></code> 配置是一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">LazyObject</span></code> ，当尚未访问设置时，它会自动配置自己）。</p>\n<p>因此，如果有一个包含一些代码的模块，如下所示：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.conf</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">settings</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">get_callable</span>\n\n<span class=\"n\">default_foo_view</span> <span class=\"o\">=</span> <span class=\"n\">get_callable</span><span class=\"p\">(</span><span class=\"n\">settings</span><span class=\"o\">.</span><span class=\"n\">FOO_VIEW</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>…然后导入此模块将导致设置对象被配置。 这意味着第三方在顶层导入模块的能力与手动配置设置对象的能力不兼容，或者在某些情况下使其变得非常困难。</p>\n<p>为了替换上面的代码，必须使用惰性级别或间接级别，例如 <code class=\"docutils literal notranslate\"><span class=\"pre\">django.utils.functional.LazyObject</span></code> ， <code class=\"docutils literal notranslate\"><span class=\"pre\">django.utils.functional.lazy()</span></code> 或者 <code class=\"docutils literal notranslate\"><span class=\"pre\">lambda</span></code> 。</p>\n</section>\n<section id=\"miscellaneous\">\n<h2>杂项<a class=\"heading-anchor\" href=\"#miscellaneous\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<ul class=\"simple\">\n<li><p>为国际化标记所有的字符串；更多细节请参见 <a class=\"reference internal\" href=\"/zh-hans/5.0/topics/i18n/\"><span class=\"doc\">i18n documentation</span></a>。</p></li>\n<li><p>在更改代码时，删除不再使用的 <code class=\"docutils literal notranslate\"><span class=\"pre\">import</span></code> 语句。<a class=\"extlink-pypi reference external\" href=\"https://pypi.org/project/flake8/\">flake8</a> 将为你识别这些未使用的导入。如果需要保留一个未使用的导入以保持向后兼容性，请在末尾标记为 <code class=\"docutils literal notranslate\"><span class=\"pre\">#</span> <span class=\"pre\">NOQA</span></code> 以消除 flake8 的警告。</p></li>\n<li><p>按部就班的删除代码结尾那些增加不必要字节的空格，增加了显示混乱还可能导致偶尔的合并冲突。一些IDE可以通过配置自动删除它们，大多数版本控制工具可以在差异比较时高亮显示它们。</p></li>\n<li><p>请不要在你贡献的代码里面放入你的名字，我们的政策是把贡献者名字保存到随Django分发的AUTHORS文件里--—而不是分散在代码库里。如果你进行的不只是一次简单修改，请随意更改在你补丁中的AUTHORS文件。</p></li>\n</ul>\n</section>\n<section id=\"javascript-style\">\n<h2>JavaScript 样式<a class=\"heading-anchor\" href=\"#javascript-style\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>关于 Django 所使用 JavaScript 代码样式的更多内容，请参见 <a class=\"reference internal\" href=\"/zh-hans/5.0/internals/contributing/writing-code/javascript/\"><span class=\"doc\">JavaScript</span></a>。</p>\n</section>","rootId":"coding-style","toc":[{"title":"预提交检查","anchor":"pre-commit-checks","children":[]},{"title":"Python 编码风格","anchor":"python-style","children":[]},{"title":"导入","anchor":"imports","children":[]},{"title":"模版风格","anchor":"template-style","children":[]},{"title":"视图风格","anchor":"view-style","children":[]},{"title":"模型风格","anchor":"model-style","children":[]},{"title":"django.conf.settings 配置的使用","anchor":"use-of-django-conf-settings","children":[]},{"title":"杂项","anchor":"miscellaneous","children":[]},{"title":"JavaScript 样式","anchor":"javascript-style","children":[]}],"breadcrumbs":[{"docname":"internals/index","title":"Django内部","url":"/zh-hans/5.0/internals/"},{"docname":"internals/contributing/index","title":"为 Django 做贡献","url":"/zh-hans/5.0/internals/contributing/"},{"docname":"internals/contributing/writing-code/index","title":"编写代码","url":"/zh-hans/5.0/internals/contributing/writing-code/"}],"prev":{"docname":"internals/contributing/writing-code/index","title":"编写代码","url":"/zh-hans/5.0/internals/contributing/writing-code/"},"next":{"docname":"internals/contributing/writing-code/unit-tests","title":"单元测试集","url":"/zh-hans/5.0/internals/contributing/writing-code/unit-tests/"},"formats":{"html":"/zh-hans/5.0/internals/contributing/writing-code/coding-style/","markdown":"/zh-hans/5.0/internals/contributing/writing-code/coding-style.md","json":"/zh-hans/5.0/internals/contributing/writing-code/coding-style.json"},"source":"https://github.com/django/django/blob/stable/5.0.x/docs/internals/contributing/writing-code/coding-style.txt","official":"https://docs.djangoproject.com/zh-hans/5.0/internals/contributing/writing-code/coding-style/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}