우리는 Django 서버를 돌리기 위 python manage.py runserver를 돌려왔다. 이제는 이러한 명령어를 직접 만들어보자.
명령어 클래스는 BaseCommand를 상속해야 한다. BaseCommand를 살펴보면 (base.py에 이미 설명이 다 잘 되어 있다)
다음과 같이 안내해주고 있다.
"""
The base class from which all management commands ultimately
derive.
Use this class if you want access to all of the mechanisms which
parse the command-line arguments and work out what code to call in
response; if you don't need to change any of that behavior,
consider using one of the subclasses defined in this file.
If you are interested in overriding/customizing various aspects of
the command-parsing and -execution behavior, the normal flow works
as follows:
1. ``django-admin`` or ``manage.py`` loads the command class
and calls its ``run_from_argv()`` method.
.... 중략
뭔가 궁금하거나 새로운 기능을 넣고 싶을 때는 공식 문서나 base.py를 참고하면 된다.
python manage.py loveyou --times 5 를 입력하면 love you를 5번 출력하는 명령어를 만들어 보도록하자.
1. 우선 startapp을 통해 설정한 app 아무 곳에나 (사실 명령어가 영향을 미칠 적절한 app에 넣어주는 게 맞지만 시험삼아 해보는 테스트이니까 아무 곳에나...) management 폴더를 생성 한 후 __init__.py를 만들어주고, 그 폴더 내부에 commands 폴더를 생성 한 후 __init__.py를 생성해주면 된다.
해당 폴더 이름들은 프레임워크의 규칙이므로 무조건 따라야 합니다.
To do this, add a management/commands directory to the application. Django will register a manage.py command for each Python module in that directory whose name doesn’t begin with an underscore. For example:
2. 이제 commands 폴더 내부에 우리가 만든 명령어인 loveyou.py를 만든 후 다음과 같이 작성해주자. BaseCommand는 커맨드를 만들기 위해 반드시 상속해야 할 것이다.
from django.core.management.base import BaseCommand
class Command(BaseCommand):
pass
3. python manage.py loveyou를 입력하면 handle() 메서드가 없다고 오류를 낸다.
'subclasses of BaseCommand must provide a handle() method'
base.py에 있는 BaseCommand 클래스를 직접 살펴 보면 다음과 같이 잘 설명 되어 있다.
def handle(self, *args, **options):
"""
The actual logic of the command. Subclasses must implement
this method.
"""
raise NotImplementedError('subclasses of BaseCommand must provide a handle() method')
이를 이용하여 다음과 같이 작성해보았다.
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = 'this command tell you love you'
def add_arguments(self, parser):
parser.add_argument("--times", help="How many times?")
def handle(self, *args, **options):
print(args, options)
print("i love you")
이제 python manage.py loveyou --times 5를 입력하면 출력 결과는 다음과 같이 나온다.
()
{'verbosity': 1, 'settings': None, 'pythonpath': None, 'traceback': False, 'no_color': False, 'force_color': False, 'times': '5'}
i love you
5번 출력이 되게 해야하므로 handle 함수를 다음과 같이 수정해주었다.
def handle(self, *args, **options):
print("i love you\n" * int(options.get("times")))
이제 명령어는 정상적으로 작동한다!
추가로, 다음과 같이 BaseCommand.style 을 줘서 출력하면, 파랑 글씨로 출력할 수도 있다.
문제는 윈도우에서는 보이지 않는다...
self.stdout.write(self.style.SUCCESS("I LOVE YOU\n") * int(options["times"]))
'Django, Flask > 🔫 Django' 카테고리의 다른 글
url과 view(FBV), django templates (0) | 2020.06.14 |
---|---|
django-seed와 faker를 이용해 커스텀 명령어로 데이터 생성하기 (0) | 2020.05.13 |
모델 메서드 오버라이딩 : save()와 delete() 덮어쓰기 (0) | 2020.05.13 |
어드민 패널 개선하기: raw_id_field, inline admin (0) | 2020.05.13 |
업로드 다루기: Meida와 static의 차이, mark_safe (0) | 2020.05.13 |