09.-1 테스트 데이터 생성

조재훈·2022년 7월 21일
0

Clone_Airbnb

목록 보기
18/31
post-thumbnail

1) 자작 명령어 만들기

자작 명령어를 만들고 싶으면 아무 앱이나 들어가서 management 폴더를 만든다. 그리고 그 안에 __init__.py 파일을 생성한다. (깡통이어도 됨) 이 파일의 역할은 management 폴더가 장고, 파이썬 폴더임을 알려주는 것이다.
그리고 해당 폴더 내에 commands 폴더를 추가로 생성하고 그 안에 또
__init__.py 파일을 생성한다.
자작 명령어를 담을 파일을 생성한다. 임시로 hello.py를 만들어본다.

자 그러면 이 명령을 실행해보자.

python manage.py hello --times 50


될리가 없다. 아무 명령어도 입력이 되어있지 않기 때문이다.
에러 내용을 살펴보자.

AttributeError: module 'rooms.management.commands.hello' has no attribute 'Command'

hello.py 파일에 Command 속성이 없다고 한다.
장고 문서를 참조하자.
https://docs.djangoproject.com/en/4.0/howto/custom-management-commands/

Command를 만들어야 하는데 BaseCommand 라는걸 상속받는다.
rooms - management - commands - hello.py

from django.core.management.base import BaseCommand

class Command(BaseCommand):
    print("hello")

hello라고 한번 뜨긴 하는데 에러가 뜬다. --times 에 대한 설명이 없다고 한다.

--times를 빼고 하면

BaseCommand의 하위 클래스는 반드시 handle() 메소드를 제공해야한다고 한다. BaseCommand를 타고 들어가서 보자.

3번에 보면 execute() 메소드는 파싱된 인자가 담긴 handle() 메소드를 호출함으로써 명령을 실행한다. handle()에 의해 생성된 모든 출력은 콘솔에 입력된다.
즉 handle()메소드가 출발점이다.
좀 궁금하니 더 찾아보자.
run_from_argv 메소드를 보면 인자를 받아 execute 메소드를 실행한다.

execute 메소드는 출력(output)으로 handle 메소드를 실행한다.

handle 메소드는 실제로 실행될 자작 명령어가 담기는 메소드로서 반드시 작성해야 한다. 참고로 저기 써있는 NotImplementedError 내용이 콘솔의 마지막에 뜬 에러 내용과 동일하다. handle 작성이 안되었다는 것이다.

또 살펴보면 create_parser 라는게 있다. 보니까 대시(dash) 2개를 붙여서 명령어 옵션을 추가하는 기능인듯 하다. add_base_argument 라는 메소드를 활용해서 --version, --verbosity, --settings 등의 옵션을 추가해놓은 것을 볼 수 있다.

내리다보니 add_arguments가 있고 add_base_argument가 있다. 아마 add_argument를 이용해서 기본적인 기능들을 추가하는 add_base_argument를 구현해놓은 듯 하다. 우리가 직접 자작한 기능을 추가하고 싶으면 add_arguments를 쓰라고 나와있다.
사용 방법은 add_arguments 메소드를 오버라이딩하고서 그 안에 parser.add_argument를 해서 추가할 파서를 정의해주면 된다.

저 add_argument 라는건... 파서를 다루는 겁나 긴 파일에 정의되어있다. 참고로 보자면 아래와 같다.

아무튼, 돌아와서 파서를 추가해보자.
rooms - management - commands - hello.py

from django.core.management.base import BaseCommand

class Command(BaseCommand):

    help = "This command says hello to me"
    
    def add_arguments(self, parser):
        parser.add_argument(
            "--time",
            help="How many times do you want me to tell you hello?",
        )

콘솔에서 다시 실행해보자.

python manage.py hello --times 50

--times에 대한 에러는 뜨지 않는다. 이제 handle()만 처리하면 된다.

help는 잘 정의되어있다.

아까 정의되어있던 handle을 살펴보면 인자로 *args와 **options 라는걸 받는다. 이게 뭔지 살펴보자.

    def handle(self, *args, **options):
        print("args : ", args, "\noptions : ", options)
        print("hello")

args로는 받은게 없고 options는 보니까 BaseCommand에서 이미 add_base_argument로 추가되어있는 parser들과 내가 정의한 'times' 옵션이 명시되어있다.

이제 본격적으로 handle을 작성하자.
rooms - management - commands - hello.py - Command

    def handle(self, *args, **options):
        times = int(options["times"])
        for t in range(0, times):
            print("hello")

참고로 저기 times에 등록된 것들은 int가 아닌 str이다. 따라서 int로 바꾼 후에 하지 않으면 정상적으로 실행이 안된다.

def handle(self, *args, **options):
    print("args : ", args, "\noptions : ", options)
    print(options["times"])
    print(type(options["times"]))
    print("hello")

실행결과 짠!

다른 명령어를 가져와서 좀 더 이쁘게 바꿔보자.

    def handle(self, *args, **options):
        times = int(options["times"])
        for t in range(0, times):
            self.stdout.write(self.style.SUCCESS("Hello"))
            self.stdout.write(self.style.WARNING("Hello"))
            self.stdout.write(self.style.ERROR("Hello"))

호오

profile
맨땅에 헤딩. 인생은 실전.

0개의 댓글