본문 바로가기
Django

장고를 처음 시작하는 사람들이 알아야 할 코딩 스타일 기초

by devlect 2020. 11. 21.

이 글은 장고 공식 문서를 읽고 기억에 남는 스타일 규칙을 간단히 개인적으로 정리한 것입니다. 코딩을 처음 시작하다보면 이런 사소한(?)코딩 규칙을 일정 부분 무시하면서 배우기 마련입니다. 모든 규칙을 처음부터 완벽히 배워 시작할수는 없으니까요.(이러면 배 보다 배꼽이 더 커지겠지요. 코드 리팩토링이 필요한 것이 꼭 구조적 문제만은 아닐겁니다^^) 하지만 계속 그런 코드를 쓸 순 없죠. 코딩 스타일은 여러 사람에게 쉽게 읽힐 수 있는 더 나은 방법을 알려줍니다. 

 

원문의 모든 가이드를 읽고 싶다면 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()' 문자열 포맷팅을 상황에 맞게 적절히 활용하세요.

각 문자열 포맷팅 방법을 잘 모르시겠다면 아래 예시를 한번 보시죠.

* 이걸 맞추려고 기존 코드를 리팩토링하는데 시간을 낭비하지 마세요. 앞으로 잘하면 됩니다.

 

%-formatting

>>> print('%(language)s has %(number)03d quote types.' % {'language': "Python", "number": 2})
Python has 002 quote types.

f-strings

>>> 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

댓글