테스트를 해야하는데 언제까지 일일이 손으로 클릭해서 넣거나 스페이스를 눌러가며 입력하기 귀찮았다.
그래서 데이터를 자동으로 생성해서 편하게 테스트 하기 위해 방법을 검색하다보니 django-seed라는 library를 발견했다.
목표
django-seed를 이용해 company와 1:n 관계를 가진 employee를 생성해, employee와 one-to-one relationship을 가지고 있는 모델의 데이터도 생성한다.
설치
pip install django-seed
설정
INSTALLED_APPS = (
...,
'django_seed'
)
실행
python manage.py create_employee --number 30 --settings=config.settings.deploy
python manage.py create_polls --number 30 --settings=config.settings.deploy
django manager로 실행할 명령어가 create_employee고 30개를 만들겠다는 의미다.
또, create_polls로 생성된 employee와 연관된 데이터도 30개 만든다.
number 같은 argument와 settings설정을 줘도 제대로 작동하는 것을 보여준다.
과정
django manager엔 create_employee라는 명령어가 없다.
만들어줘야 한다.
1. app 내에 model과 동일한 경로에 management/commands 폴더를 생성한다.
경로
- polls
- management
- commands
- create_employee.py (명령어의 이름이 되는 파일)
- __init__.py
- __init__.py
- commands
- management
2. create_employee.py
Employee를 생성하는 예제다.
from django.core.management.base import BaseCommand
from django_seed import Seed
from polls.models import Company
from polls.models Employee
import datetime
class Command(BaseCommand):
help = 'this command create employee'
def add_arguments(self, parser):
parser.add_argument('--number', default=1, type=int)
def handle(self, *args, **options):
number = options.get('number')
com = Company.objects.get(company_id = '...')
seeder = Seed.seeder()
seeder.add_entity(Employee, number, {
'company_id': com,
'created_dt': datatime.datetime.now()
})
seeder.excute()
add_arguments 함수를 overriding하면서 초기값, 타입 설정
default =1 은 1회가 기본이고, 입력이 int라고 알려준다.
--number 30 할때 30이 여기들어간다.
handle 함수를 overring하면서 원하는 명령어 기능 수행을 한다.
seeder = Seed.seeder()
seeder.add_entity(Employee, number, {'company_id': com,...})
seeder.excute()
Employee 모델에 number만큼 데이터를 생성한다.
값을 정하고 싶거나 커스텀하고 싶을 때, 필드명과 넣고 싶은 값을 넣는다.
company와 employee는 1:n 관계이므로 모두 동일한 com을 입력으로 해도 괜찮다.
3. create_polls.py
employee와 1:1관계를 가지고 있는 데이터를 생성한다.
from django_seed import Seed
from django.core.management.base import BaseCommand
from polls.models import Comany
from polls.models import Employee
from polls.models import Part1, Part2, Part3, Part4, Part5
import datetime
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('--number', default=1, type=int)
def handle(self, *args, **options):
com = Company.objects.get(company_id = ~)
number = options.get('number')
employees = Employee.objects.filter(company_id=com).order_by('-created_dt')[:number]
employee_list = list(employees)
today = datetime.datetime.today()
seeder = Seed.seeder()
employee_list1 = list(employees)
seeder.add_entity(Part1, number, {
'employee_id': lambda x : employee_list1.pop(0),
'created_dt': today,
'part1_1': lambda x : random.randrange(1,6),
'part1_2': lambda x : random.randrange(1,6),
...
})
employee_list2 = list(employees)
seeder.add_entity(Part2, number, {
'employee_id': lambda x : employee_list2.pop(0),
'created_dt': today,
'part2_2': lambda x : random.randrange(1,6),
...
})
...
employee_list5 = list(employees)
seeder.add_entity(Part5, number, {
'gender': lambda x : random.choice(['미혼', '기혼']),
...
})
seeder.execute()
employees = Employee.objects.filter(company_id=com).order_by('-created_dt')[:number]
com에 속한 Employee를 filter로 거르고 created_dt를 내림차순으로 number만큼 정렬한다.
최근 생성된 30개가 불려온다.
Employee하나에 Part1, ..., Part5가 한개씩 붙어야 하는데, 단순히 생성하면 unique 문제가 계속 발생했다.
단순하게 'employee_id' : random.choice(...)로 하면 운 좋으면 통과지만 대부분 중복문제가 생긴다.
그래서 employee를 리스트로 만들어서 pop(0)를 사용해 이미 만들어진 employee는 리스트에서 제거해 중복 문제를 해결했다.
seeder.add_entity(Part1, number, {'employee_id': lambda x : employee_list1.pop(0)})
seeder.add_entity(Part1, number, {'employee_id': employee_list1.pop(0)})
은 차이가 있다.
위에는 30개의 Part1가 각각 다른 employee에 연결되어 생성된다. Part1 - A / Part1 - B ... 이런식으로
아래는 30개의 Part1가 같은 employee에 연결되어 30개 생성된다. Part1 - A * 30 이렇게
따라서 lambda x 의 역할이 중요하다.
'part1_1' : lambda x : random.randrange(1,6) 도 마찬가지다.
lambda x 를 안하고 random.randrage(1,6) 만하면 30개 Part1의 part1_1필드는 모두 동일하다.
lambda x 를 해줘야 30개의 part1_1필드가 랜덤하게 다르게 생성된다.
'IT > Django' 카테고리의 다른 글
[crontab] django-crontab (0) | 2021.02.20 |
---|---|
[python] makedirs, mkdir 차이 (0) | 2021.01.14 |
[ CORS ] Cross Origin 리소스 공유 에러 해결 (0) | 2021.01.04 |
django nginx ssl 적용 (0) | 2020.09.23 |
convert model to sql query (0) | 2020.09.16 |