이번에는 Youtube JustDjango의 Creating a Django Boilerplate 시리즈를 해보도록 하겠다.
www.youtube.com/watch?v=qrsq8g6bqbE&list=PLLRM7ROnmA9FgFlqn-HHBz0LJ62qJBwSw&index=4
지금 어떤 종류의 Custom Commands가 필요한가?
우리는 현재 Django Boilerplate
를 만들고 있다. 이 Boilerplate
의 역할은 미리 준비된 Django Project
를 만들어서 필요할 때마다 적용시키거나, 새로운 Django Project
를 만들 때 기반이 되게끔 하여 시간을 단축시키기 위함이다. 더 자세한 사항은 여기에서 알아볼 수 있다. 우선 우리의 폴더들을 보자:
# project folder structure
src
├── demo
├── .env
├── db.sqlite3
└── manage.py
하지만 우리가 demo
라는 이름의 프로젝트가 아닌 다른 이름의 프로젝트를 원한다면 어떻게 해야할 것인가?? Django
가 자체적으로 프로젝트의 이름을 바꾸는 커맨드가 있으면 좋겠으나, 없으므로 우리가 새로 만들어줘야한다.
app 만들고 폴더를 구현하기
우선, core
이라는 이름의 app
을 하나 구현해보도록 하자:
>>> python manage.py startapp core
이렇게 한다면 다음과 같은 폴더 구조를 가지게 될 것이다:
src
├── core
├── demo
├── .env
├── db.sqlite3
└── manage.py
일단 우리가 만든 app
이 제대로 구현되게 하기 위해, base.py
를 수정시켜준다:
# demo/settings/base.py
...
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'core.apps.CoreConfig',
]
...
그리고 그 안에 management
, commands
, rename.py
를 순서대로 만든다:
src
├── core
│ └── management
│ └──commands
│ └── rename.py
├── demo
├── .env
├── db.sqlite3
└── manage.py
이제 한번 powershell
이나 cmd
에 다음과 같이 쳐보자:
>>> python manage.py help
...
Type 'manage.py help <subcommand>' for help on a specific subcommand.
Available subcommands:
[auth]
changepassword
createsuperuser
[contenttypes]
remove_stale_contenttypes
[core]
rename
[debug_toolbar]
debugsqlshell
[django]
check
compilemessages
createcachetable
dbshell
diffsettings
dumpdata
flush
inspectdb
loaddata
makemessages
makemigrations
migrate
sendtestemail
shell
showmigrations
sqlflush
sqlmigrate
sqlsequencereset
squashmigrations
startapp
startproject
test
testserver
[sessions]
clearsessions
[staticfiles]
collectstatic
findstatic
runserver
중간에 보면 [core] rename
이라고 되어 있는 것을 볼 수 있을 것이다. 이 뜻은 우리가 이 rename.py
에 적절한 커맨드들을 쓴다면 제대로 된 커맨드로 구현시킬 수 있다는 것이다. 이제 rename.py
를 한번 구현해보자:
from django.core.management.base import BaseCommand
import os
class Command(BaseCommand):
help = 'Renames a Django Project'
def add_arguments(self, parser):
parser.add_argument('new_project_name', type=str, help='The new Django Project Name')
def handle(self, *args, **kwargs):
new_project_name = kwargs['new_project_name']
files_to_rename = ['demo/settings/base.py', 'demo/wsgi.py', 'manage.py']
folder_to_rename = 'demo'
for f in files_to_rename:
with open(f, 'r') as file:
filedata = file.read()
filedata = filedata.replace('demo', new_project_name)
with open(f, 'w') as file:
file.write(filedata)
os.rename(folder_to_rename, new_project_name)
self.stdout.write(self.style.SUCCESS('Project has been renamed to %s' % new_project_name))
- 우선
Custom Command
를 만들기 위해서는django.core.management.base
에서BaseCommand
를 가지고 와서,Command
라는 클래스에 정의를 해주어야 한다. - 클래스 안의
help
는 이 커맨드에 대한 정보를 알아보고 싶을 때 사용자에게 보여주기 위함이다. add_arguments(self, parser)
에서parser
은 새로운 변수를 우리의 커맨드에 클래스에 추가하기 위해 있다.'new_project_name'
은 이 변수의 이름이 될 것이고,type=str
은 이 변수의 종류, 즉 여기서는 문자열로 정의를 하고, 마지막의help
는 위의help
와 비슷한 용도로 사용된다.handle
함수에는 실제 이 커맨드에서 우리가 하고자 하는 로직이 들어가야 한다. 여기서 보면handle(self, *args, **kwargs)
로new_project_name
은 위의add_argument
함수에서 정의한'new_project_name'
을 딕셔너리로 통과시켜준다.- 다음에는
files_to_rename
과folder_to_rename
인데,files_to_rename
같은 경우는 우리가 바꿔야 하는 부분들, 즉 이 경우demo
라는 명칭이 들어 가 있는 중요한 파일들을 지정해주면 된다. 이 프로젝트의 경우는base.py
,wsgi.py
,manage.py
가 포함이 되므로 이 세가지를 포함시켜주면 된다. 확장자명까지 쓰는 것에 유의하도록 하자.folder_to_rename
는files_to_rename
이후에 정의가 되어야 하는데, 그래야 안에 있는 파일들이 먼저 이름이 바뀌고 마지막에 폴더의 이름이 바뀌면서 충돌이 일어나지 않게끔 할 수 있기 때문이다. - 다음은 파일들을 읽어들이고 새로 바꿔주는 것이다. 단순한 것이므로 건너 뛰도록 하겠다.
os.rename(folder_to_rename, new_project_name)
는 안의 파일들이 아닌 폴더의 이름을 바꾸는 역할을 한다.- 마지막으로
self.stdout.write(self.style.SUCCESS('Project has been renamed to %s' % new_project_name))
는,powershell
또는cmd
에 성공 메세지를 출력해주는 역할을 한다.
실제로 다음과 같이 입력하면, 성공 메세지를 볼 수 있다:
>>> python manage.py rename baseapp
...
Project has been renamed to baseapp
이번 포스팅에서는 매우 간략하게 Django Custom Commands
에 대해 알아보았다. 이것으로 Django Boilerplate Project
는 여기서 마칠 수 있도록 하겠다.