# Django 5.2.9 문서

# 코딩 스타일

장고에 포함시킬 코드를 작성할 때 이러한 코딩 표준을 따르십시오.

## 사전 커밋 검사

“pre-commit <https://pre-commit.com>”_은(는) 사전 커밋 후크를 관리하기 위한 프레임워크입니다. 이러한 훅은 검토를 위해 코드를 커밋하기 전에 간단한 문제를 식별하는 데 도움이 됩니다. 코드 검토 전에 이러한 문제를 확인함으로써 검토자는 변경 자체에 집중할 수 있으며 CI 실행 횟수를 줄이는 데 도움이 될 수 있습니다.

도구를 사용하려면 먼저 “pre-commit”을 설치한 다음 Git 훅을 설치합니다.

/ 

    $ python -m pip install pre-commit
    $ pre-commit install

    ...\> py -m pip install pre-commit
    ...\> pre-commit install

첫 번째 커밋 “pre-commit”에서 후크를 설치합니다. 후크는 자체 환경에 설치되며 첫 번째 실행에서 설치하는 데 시간이 조금 걸립니다. 이후의 점검은 상당히 빠를 것입니다. 오류가 발견되면 해당 오류 메시지가 표시됩니다. 오류가 “black” 또는 “isort”에서 발생한 경우 도구가 진행하여 오류를 수정해 줍니다. 변경 사항을 검토하고 마음에 드는 경우 커밋을 위해 다시 스테이징하십시오.

## 파이썬 스타일

- All files should be formatted using the black auto-formatter. This will be run by `pre-commit` if that is configured.

- 프로젝트 저장소에는 “.editorconfig’ 파일이 포함되어 있습니다. 들여쓰기 및 공백 문제를 방지하려면 “EditorConfig”_ 지원 텍스트 편집기를 사용하는 것이 좋습니다. 파이썬 파일은 들여쓰기에 4개의 공간을 사용하고 HTML 파일은 2개의 공간을 사용합니다.

- 별도로 지정하지 않는 한:pep:’8’을 따른다.

  Use flake8 to check for problems in this area. Note that our `.flake8` file excludes some errors that we don’t consider as gross violations. Remember that PEP 8 is only a guide, so respect the style of the surrounding code as a primary goal.

  An exception to PEP 8 is our rules on line lengths. We allow up to 88 characters in code, as this is the line length used by `black`. Documentation, comments, and docstrings should be wrapped at 79 characters. These limits are checked when `flake8` is run.

- String variable interpolation may use %-formatting, f-strings, or `str.format()` as appropriate, with the goal of maximizing code readability.

  가독성에 대한 최종 판단은 합병의 재량에 맡겨집니다. 참고로 f-string은 일반 변수 및 속성 액세스만 사용해야 하며, 더 복잡한 경우에는 사전 로컬 변수가 할당되어야 합니다.

      # Allowed
      f"hello {user}"
      f"hello {user.name}"
      f"hello {self.user.name}"

      # Disallowed
      f"hello {get_user()}"
      f"you are {user.age * 365.25} days old"

      # Allowed with local variable assignment
      user = get_user()
      f"hello {user}"
      user_days_old = user.age * 365.25
      f"you are {user_days_old} days old"

  오류 및 로깅 메시지를 포함하여 변환이 필요할 수 있는 문자열에는 f-messages를 사용하면 안 됩니다. 일반적으로 “format()”은 더 장황하기 때문에 다른 포맷 방법을 선호합니다.

  포맷 방법을 조정하기 위해 기존 코드의 관련 없는 리팩터링을 하는 데 시간을 낭비하지 마십시오.

- “We loop over”가 아닌 “Loop over”와 같은 주석에서 “We”를 사용하지 마십시오.

- 변수, 함수 및 메서드 이름에는 camelCase가 아닌 밑줄을 사용합니다(즉, “poll.get_unique_voters()”는 “poll.getUniqueVoters()”가 아닙니다.

- 클래스 이름(또는 클래스를 반환하는 공장 함수의 경우)에는 “InitialCaps”를 사용합니다.

- 문서 문자열에서 기존 문서 문자열의 스타일을 따릅니다.

- 테스트에서는 :meth:’~django.test를 사용합니다.SimpleTestCase.assertRaisesMessage’ 및 :meth:’~django.test.:meth:’~unittest 대신 SimpleTestCase.assertWarnsMessage’를 사용합니다.TestCase.assertRaise’ 및 :meth:’~unittest.예외 또는 경고 메시지를 확인할 수 있도록 TestCase.assertWarns’를 참조하십시오. :meth:’~unit test를 사용합니다.TestCase.assertRegex’ 및 :meth:’’~unittest.정규식 일치가 필요한 경우에만 TestCase.assertWarnsRegex’를 입력합니다.

  :meth:’assertIs(…, True/False)<unittest를 사용합니다.TestCase.assert:meth:’~unittest가 아닌 부울 값을 테스트하기 위한 Is>’입니다.TestCase.assertTrue’와 :meth:’~단위 테스트.TestCase.assertFalse’를 사용하면 식의 진실성이 아닌 실제 부울 값을 확인할 수 있습니다.

- 테스트 문서 문자열에 각 테스트가 보여주는 예상 동작을 기술합니다. “테스트 대상” 또는 “확인 대상”과 같은 프리암블은 포함하지 마십시오.

  티켓에 문서 문자열이나 설명에서 쉽게 설명할 수 없는 추가 세부 정보가 있는 모호한 문제에 대한 티켓 참조를 예약합니다. 다음과 같은 문장의 끝에 티켓 번호를 포함합니다.

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

- Where applicable, use unpacking generalizations compliant with PEP 448, such as merging mappings (`{**x, **y}`) or sequences (`[*a, *b]`). This improves performance, readability, and maintainability while reducing errors.

## 수입

- Use isort to automate import sorting using the guidelines below.

  빠른 시작:

  / 

      $ python -m pip install "isort >= 7.0.0"
      $ isort .

      ...\> py -m pip install "isort >= 7.0.0"
      ...\> isort .

  이렇게 하면 현재 디렉토리에서 “isort”가 반복적으로 실행되어 지침에 맞지 않는 파일이 수정됩니다. 순환 가져오기를 피하기 위해 가져오기를 순서가 잘못된 상태로 만들어야 하는 경우 다음과 같은 설명을 사용하십시오.

      import module  # isort:skip

- Put imports in these groups: future, standard library, third-party libraries, other Django components, local Django component, try/excepts. Sort lines in each group alphabetically by the full module name. Place all `import module` statements before `from module import objects` in each section. Use absolute imports for other Django components and a one-dot relative import (`from .foo import Bar`) for local components. Avoid multi-dot relative imports.

- 각 줄에서 소문자 항목 앞에 그룹화된 대문자 항목을 알파벳 순으로 입력합니다.

- 괄호를 사용하여 긴 줄을 끊고 연속선을 4칸씩 들여씁니다. 마지막 가져오기 뒤에 후행 쉼표를 포함하고 닫는 괄호를 자체 행에 배치합니다.

  마지막 가져오기 코드와 모듈 수준 코드 사이에 하나의 빈 줄을 사용하고 첫 번째 함수 또는 클래스 위에 있는 두 개의 빈 줄을 사용합니다.

  예를 들어, (주석은 설명 목적으로만 작성됩니다.)

  `django/contrib/admin/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: ...

- Use convenience imports whenever available. For example, do this

      from django.views import View

  대신:

      from django.views.generic.base import View

## 템플릿 스타일

Follow the below rules in Django template code.

- `{% extends %}` should be the first non-comment line.

  다음 작업을 하세요.

      {% extends "base.html" %}

      {% block content %}
        <h1 class="font-semibold text-xl">
          {{ pages.title }}
        </h1>
      {% endblock content %}

  Or this:

      {# This is a comment #}
      {% extends "base.html" %}

      {% block content %}
        <h1 class="font-semibold text-xl">
          {{ pages.title }}
        </h1>
      {% endblock content %}

  다음 작업은 하지마세요.

      {% load i18n %}
      {% extends "base.html" %}

      {% block content %}
        <h1 class="font-semibold text-xl">
          {{ pages.title }}
        </h1>
      {% endblock content %}

- Put exactly one space between `{{`, variable contents, and `}}`.

  다음 작업을 하세요.

      {{ user }}

  다음 작업은 하지마세요.

      {{user}}

- In `{% load ... %}`, list libraries in alphabetical order.

  다음 작업을 하세요.

      {% load i18n l10 tz %}

  다음 작업은 하지마세요.

      {% load l10 i18n tz %}

- Put exactly one space between `{%`, tag contents, and `%}`.

  다음 작업을 하세요.

      {% load humanize %}

  다음 작업은 하지마세요.

      {%load humanize%}

- Put the `{% block %}` tag name in the `{% endblock %}` tag if it is not on the same line.

  다음 작업을 하세요.

      {% block header %}

        Code goes here

      {% endblock header %}

  다음 작업은 하지마세요.

      {% block header %}

        Code goes here

      {% endblock %}

- Inside curly braces, separate tokens by single spaces, except for around the `.` for attribute access and the `|` for a filter.

  다음 작업을 하세요.

      {% if user.name|lower == "admin" %}

  다음 작업은 하지마세요.

      {% if user . name | lower  ==  "admin" %}

      {{ user.name | upper }}

- Within a template using `{% extends %}`, avoid indenting top-level `{% block %}` tags.

  다음 작업을 하세요.

      {% extends "base.html" %}

      {% block content %}

  다음 작업은 하지마세요.

      {% extends "base.html" %}

        {% block content %}
        ...

## 보기 스타일

- Django 뷰에서 뷰 함수의 첫 번째 매개변수는 “request”라고 불러야 한다.

  다음 작업을 하세요.

      def my_view(request, foo): ...

  다음 작업은 하지마세요.

      def my_view(req, foo): ...

## 모델 스타일

- 필드 이름은 모두 소문자여야 하며, 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)

- “class 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):
          class Meta:
              verbose_name_plural = "people"

          first_name = models.CharField(max_length=20)
          last_name = models.CharField(max_length=40)

- 모델 내부 클래스 및 표준 방법의 순서는 다음과 같아야 합니다(모두 필요한 것은 아닙니다).

  - 모든 데이터베이스 필드

  - 사용자 지정 관리자 특성

  - ‘’’클래스 메타’’’’

  - `def __str__()` and other Python magic methods

  - `def save()`

  - `def get_absolute_url()`

  - 모든 사용자 지정 메서드

- If `choices` is defined for a given model field, define each choice as a mapping, with an all-uppercase name as a class attribute on the model. Example:

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

  Alternatively, consider using Enumeration types:

      class MyModel(models.Model):
          class Direction(models.TextChoices):
              UP = "U", "Up"
              DOWN = "D", "Down"

## “django.conf.settings”를 사용합니다.

모듈은 일반적으로 최상위 레벨의 “django.conf.settings”에 저장된 설정을 사용하면 안 됩니다(즉, 모듈을 가져올 때 평가됨). 이에 대한 설명은 다음과 같습니다.

설정을 수동으로 구성합니다(즉, :envvar에 의존하지 않음).’DJANGO_SETTINGS_MODULE’ 환경 변수)는 다음과 같이 허용되며 가능합니다.

    from django.conf import settings

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

그러나 ‘’settings.configure’’ 줄 앞에 있는 설정에 액세스하면 이 설정은 작동하지 않습니다. (내부적으로 ‘’settings’’는 설정이 아직 구성되지 않은 경우 자동으로 설정되는 “LazyObject”입니다.)

따라서 다음과 같은 코드가 포함된 모듈이 있으면 다음과 같이 하십시오.

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

    default_foo_view = get_callable(settings.FOO_VIEW)

…그러면 이 모듈을 가져오면 설정 개체가 구성됩니다. 즉, 타사가 최상위 수준에서 모듈을 가져오는 기능은 설정 개체를 수동으로 구성하는 기능과 호환되지 않거나 일부 상황에서는 매우 어렵습니다.

위의 코드 대신``django.utils.functional.LazyObject`` `django.utils.functional.lazy()` 나 ``lambda``와 같은 간접적인 수준을 사용해야 합니다.

## 기타

- 국제화에 대한 모든 줄에 마크를 한 후 더 자세한 내용을 원한다면 문서:`i18n `를 보세요

- Remove `import` statements that are no longer used when you change code. flake8 will identify these imports for you. If an unused import needs to remain for backwards-compatibility, mark the end of with `# NOQA` to silence the flake8 warning.

- 불필요한 바이트가 추가되고 패치가 시각적으로 복잡해지며 불필요한 병합 충돌이 발생할 수 있으므로 코드에서 모든 후행 공백을 체계적으로 제거합니다. 일부 IDE는 IDE를 자동으로 제거하도록 구성할 수 있으며 대부분의 VCS 도구는 IDE를 diff 출력으로 강조 표시하도록 설정할 수 있습니다.

- 기여하는 코드에 이름을 넣지 마십시오. 우리의 정책은 장고와 함께 배포된 “AUTHORS” 파일에 기여자의 이름을 보관하는 것입니다. 사소한 것 이상의 변경을 가할 경우 패치에 “AUTHORS” 파일의 변경 내용을 포함시키십시오.

## JavaScript 스타일

For details about the JavaScript code style used by Django, see JavaScript code.