Coding style

编写代码以包含在Django中时,请遵循这些编码标准。

Python style

  • 请符合.editorconfig文件中指定的缩进样式。 我们建议使用带有EditorConfig支持的文本编辑器来避免缩进和空格问题。 Python文件使用4个空格缩进,HTML文件使用2个空格。

  • 除非另有规定,请遵循 PEP 8

    使用flake8检查此区域中的问题。 请注意,我们的setup.cfg文件包含一些排除的文件(不推荐使用的模块,我们不关心清理和一些第三方代码Django供应商)以及一些排除的错误,我们不认为是严重违反。 请记住, PEP 8只是一个指南,因此请将周围代码的风格作为主要目标。

    PEP 8的例外是我们对线长度的规则。 如果代码看起来明显更丑陋或更难阅读,请不要将代码行限制为79个字符。 我们允许最多119个字符,因为这是GitHub代码审查的宽度;任何更长的需要水平滚动,这使得审查更加困难。 当您运行flake8时,会包含此检查。 即使 PEP 8建议72,文档,注释和文档字符串应包含79个字符。

  • 使用四个空格缩进。

  • 使用四个空间悬挂缩进而不是垂直对齐:

    raise AttributeError(
        'Here is a multine error message '
        'shortened for clarity.'
    )
    

    代替:

    raise AttributeError('Here is a multine error message '
                         'shortened for clarity.')
    

    这使得更好地利用空间,并避免在第一行的长度改变时必须重新对齐字符串。

  • 对于字符串使用单引号,如果字符串包含单引号,则使用双引号。 不要浪费时间做现代代码的无关重构以符合这种风格。

  • 避免在评论中使用“我们”,例如“循环”而不是“我们循环”。

  • 对于变量,函数和方法名称(即poll.get_unique_voters()而不是poll.getUniqueVoters()),使用下划线,而不是camelCase。

  • 对类名(或返回类的工厂函数)使用InitialCaps

  • 在docstrings中,遵循现有文档的样式和 PEP 257

  • 在测试中,使用assertRaisesMessage()而不是assertRaises(),以便您可以检查异常消息。 只有在需要正则表达式匹配时才使用assertRaisesRegex()

  • 在测试docstrings中,说明每个测试演示的预期行为。 不包括“测试”或“确保”的前导码。

    预订机票参考,用于晦涩的问题,其中机票的附加细节不容易在文档或评论中描述。 在这样一个句子的末尾包括门票号码:

    def test_foo():
        """
        A test docstring looks like this (#123456).
        """
        ...
    

进口¶ T0>

  • 使用isort可以使用以下准则自动导入排序。

    快速开始:

    $ pip install isort
    $ isort -rc .
    

    从当前目录中递归运行isort,修改任何不符合准则的文件。 如果您需要导入不合规格(例如避免循环导入),请使用如下注释:

    import module  # isort:skip
    
  • 将导入放在这些组中:未来,标准库,第三方库,其他Django组件,本地Django组件,try / excepts。 按照完整的模块名称按字母顺序排列每个组中的行。 模块 导入之前的所有导入 对象 对其他Django组件使用绝对导入,并为本地组件使用相对导入。

  • 在每一行上,按大小写项目分组的大写项目将项目按字母顺序排列。

  • 使用括号和缩进的连续行用4个空格打破长行。 在最后一次导入之后包括一个逗号,并将括号放在自己的行上。

    在最后一个导入和任何模块级代码之间使用单个空白行,并使用第一个函数或类之上的两个空白行。

    例如(注释仅供说明用途):

    Django的/的contrib /管理/ example.py
    # future
    from __future__ import unicode_literals
    
    # standard library
    import json
    from itertools import chain
    
    # third-party
    import bcrypt
    
    # Django
    from django.http import Http404
    from django.http.response import (
        Http404, HttpResponse, HttpResponseNotAllowed, StreamingHttpResponse,
        cookie,
    )
    
    # local Django
    from .models import LogEntry
    
    # try/except
    try:
        import yaml
    except ImportError:
        yaml = None
    
    CONSTANT = 'foo'
    
    
    class Example(object):
        # ...
    
  • 每当可用时使用便利导入。 例如,执行以下操作:

    from django.views import View
    

    代替:

    from django.views.generic.base import View
    

Template style

  • 在Django模板代码中,在大括号和标记内容之间放置一个(且只有一个)空格。

    做这个:

    {{ foo }}
    

    不要这样:

    {{foo}}
    

View style

  • 在Django视图中,视图函数中的第一个参数应该是request

    做这个:

    def my_view(request, foo):
        # ...
    

    不要这样:

    def my_view(req, foo):
        # ...
    

Model style

  • 字段名称应该全部为小写,使用下划线而不是camelCase。

    做这个:

    class Person(models.Model):
        first_name = models.CharField(max_length=20)
        last_name = models.CharField(max_length=40)
    

    不要这样:

    class Person(models.Model):
        FirstName = models.CharField(max_length=20)
        Last_Name = models.CharField(max_length=40)
    
  • 在定义字段之后, Meta应出现在之后,用一个空白行分隔字段和类定义。

    做这个:

    class Person(models.Model):
        first_name = models.CharField(max_length=20)
        last_name = models.CharField(max_length=40)
    
        class Meta:
            verbose_name_plural = 'people'
    

    不要这样:

    class Person(models.Model):
        first_name = models.CharField(max_length=20)
        last_name = models.CharField(max_length=40)
        class Meta:
            verbose_name_plural = 'people'
    

    不要这样做,要么:

    class Person(models.Model):
        class Meta:
            verbose_name_plural = 'people'
    
        first_name = models.CharField(max_length=20)
        last_name = models.CharField(max_length=40)
    
  • 如果你定义一个__str__方法(以前__unicode__,在支持Python 3之前),请使用python_2_unicode_compatible()装饰模型类。

  • 模型内部类和标准方法的顺序应该如下(注意,这些并不都是必需的):

    • 所有数据库字段
    • 自定义管理器属性
    • class Meta
    • def __ str __()
    • def save()
    • def get_absolute_url()
    • 任何自定义方法
  • 如果为给定模型字段定义了choices,请将每个选项定义为元组的元组,其中全大写名称作为模型上的类属性。 例如:

    class MyModel(models.Model):
        DIRECTION_UP = 'U'
        DIRECTION_DOWN = 'D'
        DIRECTION_CHOICES = (
            (DIRECTION_UP, 'Up'),
            (DIRECTION_DOWN, 'Down'),
        )
    

Use of django.conf.settings

模块通常不应该使用存储在顶层的django.conf.settings中的设置(即导入模块时进行评估)。 解释如下:

允许手动配置设置(即不依赖于DJANGO_SETTINGS_MODULE环境变量),如下所示:

from django.conf import settings

settings.configure({}, SOME_SETTING='foo')

但是,如果在settings.configure行之前访问任何设置,这将不起作用。 (在内部,settingsLazyObject,如果尚未配置,则在访问设置时自动配置本身)。

所以,如果有一个模块包含一些代码如下:

from django.conf import settings
from django.urls import get_callable

default_foo_view = get_callable(settings.FOO_VIEW)

...然后导入此模块将导致设置对象进行配置。 这意味着第三方在顶层导入模块的能力与手动配置设置对象的能力不一致,或者在某些情况下非常困难。

代替上述代码,必须使用惰性或间接级别,例如django.utils.functional.LazyObjectdjango.utils.functional.lazy()lambda

Miscellaneous

  • 标记所有字符串以进行国际化;有关详细信息,请参阅i18n documentation
  • 删除更改代码时不再使用的import语句。 flake8会为您识别这些导入。 如果未使用的导入需要保留以实现向后兼容性,请标记 NOQA的结尾,以停止flake8警告。
  • 系统地从代码中删除所有结尾的空格,因为这些添加了不必要的字节,给补丁添加了视觉混乱,并且偶尔也会导致不必要的合并冲突。 一些IDE可以配置为自动删除它们,并且大多数VCS工具可以设置为在差异输出中突出显示它们。
  • 请不要把你的名字放在你贡献的代码。 我们的政策是将贡献者的名称保存在与Django一起分发的AUTHORS文件中 - 不分散在整个代码库中。 如果您做出一个以上的细微更改,请随意在修补程序中包含对AUTHORS文件的更改。

JavaScript样式

有关Django使用的JavaScript代码样式的详细信息,请参阅JavaScript