안녕세계

[Django] Custom command 만들기 본문

[Django] Custom command 만들기

Junhong Kim 2018. 4. 30. 17:50
728x90
반응형

built-in Commands

장고 built-in command는 다음과 같습니다.

$ django-admin startapp $ django-admin startproject $ python manage.py shell $ python manage.py migrate $ python manage.py makemigrations $ python manage.py runserver

위 명령어뿐만 아니라 장고는 더 많은 built-in command를 제공합니다.
자세한 내용은 공식문서를 참고해주세요 😃

장고에서는 built-in command 가 아닌 custom command를 만들 수 있습니다.
장고 문서에서는 custom command를 다음과 같이 소개합니다.

Standalone scripts

Custom management commands are especially useful for running standalone scripts or for scripts that are periodically executed from the UNIX crontab or from Windows scheduled tasks control panel. 커스텀 관리 명령어는 특히 독립된 스크립트 또는 UNIX 크론탭, Windows 스케쥴 태스크 컨트롤 패널으로부터 주기적으로 실행되야하는 스크립트에서 특히 유용하다.

장고 문서에서 이야기한 것 처럼 이번 포스팅에서는 주기적으로 실행되야하는 스크립트
즉, 일정시간마다 특정 작업을 수행하는 기능을 커스텀 command로 만들어 보겠습니다.

django-admin commands 만들기

다음 내용은 장고 공식문서의 내용을 번역 및 정리한 내용입니다.

장고 앱은 manage.py에 내 작업(action)으로 등록할 수 있습니다. 예를들어 배포하고있는 장고 앱을 위해 manage.py에 작업을 추가할 수 있습니다. 본 포스팅에서는 tutorial project의 poll app을 위한 커스텀 closepoll command를 만들어 보겠습니다.

커스텀 커맨드는 반드시 <app_name>/management/<command_name>.py 경로에 있어야합니다.

polls/ __init__.py models.py management/ __init__.py commands/ __init__.py _private.py closepoll.py test.py views.py
  • _private.py 모듈은 management command로 이용할 수 없습니다.
  • closepoll.py 모듈은 한가지 요구사항이 필요합니다.
    • BaseCommand 또는 BaseCommand의 subclasses 중 하나를 확장하는 command 클래스를 정의해야 합니다.

그 다음 closepoll command를 사용할 수 있도록 INSTALLED_APP polls 앱을 명시해주세요.
그리고 커맨드 구현을 위해 polls/management/commands/closepoll.py 를 아래와 같이 수정합시다.

from django.core.management.base import BaseCommand, CommandError from poll.model import Question as Poll class Command(BaseCommand): help = 'Closes the specified poll for voting' def add_arguments(self, parser): parser.add_argument('poll_id', nargs= '+', type=int) def handel(self, *args, **options): for poll_id in options['poll_id'] try: poll = Poll.objects.get(pk=poll_id) except Poll.DoesNotExist: raise CommandError('Poll "%s" does not exist' % poll_id) poll.opened = False poll.save() self.stdout.write(self.style.SUCCESS('Successfully closed poll "%s"' % poll_id))

NOTE:
management command를 사용하면서 콘솔 출력을 원할 때 self.stdout  self.stderr 을 사용해야합니다. 이 같은 프록시를 사용함으로써 custom command를 보다 쉽게 테스트할 수 있습니다. 줄 바꿈 문자로 메시지를 끝내지 않아도 됩니다. 이는 특정 ending 파라미터를 명시하지 않으면 자동적으로 추가됩니다.

self.stdout.write("Unterminated line", ending='')

커스텀 커맨드는 python manage.py closepoll <poll_id>를 사용하여 호출할 수 있습니다. handle() 메서드는 하나 또는 그 이상의 poll_ids를 가져올 수 있고 각 poll.opened를 false로 지정할 수 있습니다. 만약 사용자가 존재하지 않는 poll을 참조하게되면 CommandError가 발생합니다.

Accepting optional arguments

커스텀 옵션은 add_arguments() 메서드에 추가합니다.

class Command(BaseCommand): def add_arguments(self, parser): # Positional arguments parser.add_argument('poll_id', nargs='+', type=int) # Named (optional) arguments parser.add_argument( '--delete', action='store_true', dest='delete', help='Delete poll instead of closing it', ) def handle(self, *args, **options): # ... if options['delete']: poll.delete() # ...

옵션은 위치기반 또는 이름을 명시하여 지정할 수 있습니다.

  • nargs:
    스위치나 파라미터가 받을 수 있는 값의 개수를 가리킵니다.
    이 값보다 많은 값이 들어오는 경우 무시되며 + 로 설정하는 경우 1개 이상입니다.

  • 예제의 delete 같은 옵션은 handle() 메서드의 options 딕셔너리 파라미터로 사용할 수 있습니다.add_argument 사용 방법에 대한 것은 파이썬 문서의 argparse 참고하세요.

  • handel():
    커스텀 커맨드의 기능/로직을 이 메서드 안에서 구현하면됩니다.
    커맨드 클래스의 자세한 내용은 아래를 참고해주세요.

지금까지 django에서 custom command를 만들어 보는 것을 알아보았습니다.
감사합니다. 😄

728x90
반응형
Comments