이 글은 장고 공식 문서를 읽고 기억에 남는 스타일 규칙을 간단히 개인적으로 정리한 것입니다. 코딩을 처음 시작하다보면 이런 사소한(?)코딩 규칙을 일정 부분 무시하면서 배우기 마련입니다. 모든 규칙을 처음부터 완벽히 배워 시작할수는 없으니까요.(이러면 배 보다 배꼽이 더 커지겠지요. 코드 리팩토링이 필요한 것이 꼭 구조적 문제만은 아닐겁니다^^) 하지만 계속 그런 코드를 쓸 순 없죠. 코딩 스타일은 여러 사람에게 쉽게 읽힐 수 있는 더 나은 방법을 알려줍니다.
원문의 모든 가이드를 읽고 싶다면 Coding style 를 클릭해세요.
장고 공식 문서
파이썬 스타일
- .editorconfig 따르기
대부분의 널리 알려진 에디터는 .editorconfig이라는 코딩 스타일 설정 파일을 따르도록 하는 기능을 가지고 있습니다. 여기를 눌러보면 별도의 플러그인 없이 이 기능을 지원하는 에디터를 확인할 수 있습니다. 파이참이나 비주얼 스튜디오 코드 등도 모두 포함되어 있네요.
- PEP8을 준수하되 팀의 규칙을 따르세요.
PEP는 Python Enhancement Proposal의 약자입니다. 파이썬 코드를 작성할 때 따라야 하는 가이드이자 모범 사례를 모아둔 것입니다. 이것을 기본으로 팀에서 정한 규칙을 준수하면 됩니다.
- 줄 당 글자 수는 최대 119개!
PEP8에서는 한 줄 당 79 글자를 넘지 말라고 되어 있는데 장고는 (깃허브 코드 리뷰 넓이인)119 글자를 최대 글자로 정합니다. 너무 길어지면 가로 스크롤이 생겨 리뷰할 때 불편합니다.
- 들여쓰기에는 4칸의 공백을 사용하세요.
- 아래와 같이 세로로 줄 맞추기보다는 4칸 공백을 사용한 들여쓰기를 사용하세요.
이렇게 하면 첫 줄 길이 변경에 따라 다시 맞춰줘야 하는 번거로운 일이 생기지 않습니다.
# 나쁜 예
raise AttributeError('Here is a multiline error message '
'shortened for clarity.')
# 좋은 예
raise AttributeError(
'Here is a multiline error message '
'shortened for clarity.'
)
- 홑따옴표를 기본으로 사용하세요.
홑따옴표를 포함하는 문자열이 있다면 그때 쌍따옴표를 쓰세요.
* 이걸 맞추려고 기존 코드를 리팩토링하는데 시간을 낭비하지 마세요. 앞으로 잘하면 됩니다.
- '%-formatting', 'f-strings', 'str.format()' 문자열 포맷팅을 상황에 맞게 적절히 활용하세요.
각 문자열 포맷팅 방법을 잘 모르시겠다면 아래 예시를 한번 보시죠.
* 이걸 맞추려고 기존 코드를 리팩토링하는데 시간을 낭비하지 마세요. 앞으로 잘하면 됩니다.
>>> print('%(language)s has %(number)03d quote types.' % {'language': "Python", "number": 2})
Python has 002 quote types.
>>> name = "Fred"
>>> f"He said his name is {name!r}."
"He said his name is 'Fred'."
str.format()
>>> "The sum of 1 + 2 is {0}".format(1+2)
'The sum of 1 + 2 is 3'
- '우리'와 같은 단어를 주석에 쓰지 마세요.
예를 들어, "우리는 여기서 루프를 돌면서..."와 같은 문장을 "루프를 돌면서..."로 쓰세요.
- 변수, 함수, 메소드 이름에 언더스코어를 사용하세요.
카멜케이스 스타일을 쓰지 마세요.
# Good
poll.get_unique_voters()
# Bad
poll.getUniqueVoters()
- 클래스명의 첫 글자는 대문자로.
클래스를 리턴하는 팩토리 함수도 대문자로 씁니다.
- assertIs()를 쓰세요.
asertTrue()나 assertFalse() 말고요.
- 테스트 docstrings에는 각 테스트에 기대하는 동작을 쓰세요.
표현하기 어렵고 관련 이슈 티켓이 있다면 아래처럼 찾아 볼 수 있는 이슈 티켓을 쓰면 좋습니다.
def test_foo():
"""
A test docstring looks like this (#123456).
"""
...
임포트(Import)
- 임포트에도 순서가 있습니다.
아래와 같이 각 항목을 그룹짓고 순서를 배열하세요. import module이 from module import objects보다 앞에 쓰도록 하세요.
# 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:
# ...
- 각 임포트 구문 사이는 한 줄, 마지막 임포트 구문과 함수 또는 클래스 사이는 두 줄을 띄웁니다.
- 가능한 한 편리한 임포트 방법을 쓰세요.
# GOOD
from django.views import View
# BAD
from django.views.generic.base import View
템플릿 스타일
- 중괄호와 태그 내용 사이에 한 칸을 띄웁니다.
# GOOD
{{ foo }}
# BAD
{{foo}}
뷰 스타일
- request를 줄여 쓰지 마세요.
# GOOD
def my_view(request, foo):
# ...
# BAD
def my_view(req, foo):
# ...
모델 스타일
- 필드 이름은 모두 소문자로, 카멜케이스 대신 언더스코어로.
# GOOD
class Person(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
# BAD
class Person(models.Model):
FirstName = models.CharField(max_length=20)
Last_Name = models.CharField(max_length=40)
- class Meta는 필드 정의 뒤에 쓰고 한 줄 띄웁니다.
# GOOD
class Person(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
class Meta:
verbose_name_plural = 'people'
# BAD
class Person(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
class Meta:
verbose_name_plural = 'people'
# BAD
class Person(models.Model):
class Meta:
verbose_name_plural = 'people'
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
- 모델 안의 내부 클래스와 표준 메소드는 아래 순서를 따릅니다.
필드가 언제나 가장 처음 오는 것을 잊지 마세요.
1. All database fields
2. Custom manager attributes
3. class Meta
4. def __str__()
5. def save()
6. def get_absolute_url()
7. Any custom methods
- choices 필드를 정의한다면 모두 대문자로 이루어진 튜플로 정의하세요.
class MyModel(models.Model):
DIRECTION_UP = 'U'
DIRECTION_DOWN = 'D'
DIRECTION_CHOICES = [
(DIRECTION_UP, 'Up'),
(DIRECTION_DOWN, 'Down'),
]
사소한 것들
- 문장 끝에 공백이 붙이지 마세요.
불필요한 용량이 되고, 경우에 따라 머지(merge)시 충돌이 날 수 있습니다.
- 코드에 자기 이름 쓰지 마세요.
어떤 코드에 기여했다면 AUTHORS 파일에 쓰는 겁니다. 코드 베이스 여기 저기에 이름을 흩뿌려 두지 마세요.
개인적으로 사용하는 방법
- 모델 클래스 이름은 단수로
예를 들어, Persons 이 아니라 Person으로
- 뷰에서 템플릿으로 전달하는 기본 객체는 object 그대로
이렇게 하면 중복 코드를 include로 삽입하는 등의 경우에도 with 구문없이 사용할 수 있어 편리합니다. 또, 어떤 이름으로 했지 헷갈릴 필요도 없습니다.
- related_name 은 모델의 복수로
모델의 ForeignKey 필드에는 related_name을 지정할 수 있습니다. 이 이름으로 모델의 복수형으로 해주는 겁니다. 예를 들어, Family이 있고 Person이 ForeignKey로 연결되어 있다면 Person의 related_name은 'persons'로 해주는 거지요. 이렇게 하면 family.persons 와 같이 접근할 수 있기 때문에 개념적으로도 이해하기 쉽습니다. 반대로 related_query_name를 지정하고 싶다면 단수로 해줍니다. 보통 related_query_name를 사용할 때는 해당 모델의 특정 컬럼에 filter를 사용하기 때문에 단수로 쓰는 것이 직관적입니다.
'Django' 카테고리의 다른 글
Jetbrains 설문으로 보는 Django 개발 궁금증 (0) | 2023.03.12 |
---|
댓글