Django에는 기본적으로 제공하는 command 가 존재한다.
python manage.py runserver
python manage.py makemigrations
python manage.py migrate
위와 같은 command 들이 기본적으로 제공된다.
python manage.py
로 시작하여 우리가 자주 사용하는 기본 명령어들을 Management Command
라고 한다.
우리가 사용하는 command는 manage.py
에 등록되어 사용할 수 있게 되는 것이다.
아래는 실제 python manage.py runserver
명령어 사용시에 실행되는 코드이다.
# django/core/management/commands/runserver.py
import errno
import os
import re
import socket
import sys
from datetime import datetime
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from django.core.servers.basehttp import (
WSGIServer, get_internal_wsgi_application, run,
)
from django.utils import autoreload
from django.utils.regex_helper import _lazy_re_compile
naiveip_re = _lazy_re_compile(r"""^(?:
(?P<addr>
(?P<ipv4>\d{1,3}(?:\.\d{1,3}){3}) | # IPv4 address
(?P<ipv6>\[[a-fA-F0-9:]+\]) | # IPv6 address
(?P<fqdn>[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*) # FQDN
):)?(?P<port>\d+)$""", re.X)
class Command(BaseCommand):
help = "Starts a lightweight Web server for development."
# Validation is called explicitly each time the server is reloaded.
requires_system_checks = []
stealth_options = ('shutdown_message',)
default_addr = '127.0.0.1'
default_addr_ipv6 = '::1'
default_port = '8000'
protocol = 'http'
server_cls = WSGIServer
....
runserver 명령어는 /django/core/management/commands
폴더에 runserver.py
라는 이름의 파이썬 파일로 정의 되어 있는 내용이 실행 되는 개념이다
이를 통해 기본 제공 되는 Management Command
외에도 필요에 따라 다양한 Command를 생성하여 사용 할 수 있다.
Custom Command 를 생성 하기 위해서는 생성한 app 내부에 /management/commands
폴더를 생성하고 해당 폴더 아래에 파이썬 파일을 작성 함으로 Custom Command를 생성할 수 있다.
├── init.py
├── admin.py
├── apps.py
├── management
│ └── commands
│ └── customcommand.py
├── migrations
├── models.py
├── tests.py
└── views.py
폴더와 command 파일을 생성하게 되면 다음과 같은 파일 구조를 가지게 된다.
위의 예시에서는 customcommand 라는 이름으로 파이썬 파일을 생성했고 해당 command 를 실행 할 때는 python manage.py customcommand
라는 명령어로 command를 실행하게 된다.
따라서 custom command 파일의 이름은 실제 사용할 명령어의 이름으로 command의 목적에 맞게 설정하는 것이 좋다.
이번 글에서는 Article 이라는 모델을 사용하여 command를 생성 할 것이고 model 의 내용은 아래와 같다.
from django.db import models
from django.contrib.auth.models import User
from common.models import CommonModel
class Article(CommonModel):
"""Article Model Definition"""
title = models.CharField(max_length=200)
content = models.TextField(blank=True)
writer = models.ForeignKey(
"auth.User", related_name="articles", on_delete=models.SET_NULL, null=True
)
def __str__(self):
return self.title
CommonModel
에 대한 내용은
[Django] 자주 사용하는 필드 분리
를 참고 하면 된다.
개발 단계에서 테스트를 위해 Article 모델에 데이터를 하나씩 생성하기에는 시간이 걸리고 효율적이지 않기 때문에 개발단계에서 확인할 수 있는 임의의 데이터를 생성 하기위해 Custom Command 를 작성 할 수 있다.
각 유저마다 임의의 글을 생성하는 command 는 아래와 같다.
# articles/management/commands/createarticle.py
from django.core.management import BaseCommand
from django.contrib.auth.models import User
from article.models import Article
# "Command" 라는 class 이름은 고정
class Command(BaseCommand):
# handle 함수에 command 를 통해 수행할 내용 작성
def handle(self, *args, **options):
# 전체 user 가져오기
users = User.objects.all()
for user in users:
for i in range(1, 6):
# article에 들어갈 정보 정의
payload = {
"title": f"{user.username}의 {i}번째 글",
"content": f"{i}번째 글 내용",
"writer": user
}
# 글 생성
article = Article.objects.create(**payload)
print(f"{article.id} article created.")
# 전체 성공 완료 메세지
self.stdout.write(self.style.SUCCESS('Successfully created Article'))
BaseCommand
를 상속 받은 Command
클래스 안에 handle
함수를 오버라이딩 하여 Custom Command를 통해 수행하고 싶은 기능을 정의 하면 된다.
Custom Command의 옵션을 추가 하고 싶을 때는 add_arguments
메소드를 오버라이딩 한다.
from django.core.management import BaseCommand
from django.contrib.auth.models import User
from article.models import Article
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument(
"name", type=str, help="article name", default="", nargs="?"
)
def handle(self, *args, **options):
target_name = options.get("name")
users = User.objects.all()
if target_name:
for user in users:
for i in range(1, 6):
payload = {
"title": target_name,
"content": f"{i}번째 글 내용",
"writer": user
}
article = Article.objects.create(**payload)
print(f"{article.id} article created.")
else:
for user in users:
for i in range(1, 6):
payload = {
"title": f"{user.username}의 {i}번째 글",
"content": f"{i}번째 글 내용",
"writer": user
}
article = Article.objects.create(**payload)
print(f"{article.id} article created.")
self.stdout.write(self.style.SUCCESS('Successfully created Article'))
위처럼 add_arguments
를 사용하여 커맨드에 옵션을 부여할 수 있다.
자세히 살펴보면
parser.add_argument(
"name", type=str, help="article name", default="", nargs="?"
)
위처럼 인자를 추가해서 다양한 방법으로 커맨드를 사용 할 수 있다.
Django Command는 다양한 방법으로 사용 될 수 있다. 필요시에 맞춰 사용하게 된다면 반복적인 작업을 줄여주고 효율적으로 사용할 수 있다.
글 잘 봤습니다.