도커 명령어 한줄로 장고 앱을 하나 만들어 줄게요.
docker-compose run --rm app sh -c "python manage.py startapp recipe"
recipe
앱의 구조를 아래와 같이 바꿀게요. 다른 것들은 삭제해주세요.
❯ tree recipe
recipe
├── __init__.py
├── apps.py
├── tests
│ └── __init__.py
└── views.py
1 directory, 4 files
또 앱을 만들었으면 장고에 새로운 앱을 등록도 해야겠조?!
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 3rd party apps
'rest_framework',
'rest_framework.authtoken',
# local apps
'core',
'user',
'recipe',
]
tag 객체를 다뤄주기 위해서 모델 작성을 해볼게요.
core/tests/test_models.py
로 경로를 이동하고 파일을 열어줄게요.
기존 작성된 ModelTests클래스 위에다가 sample_user()
함수를 생성할게요.
ModelTests
클래스 가장 하단에 test_tag_str
메서드를 만들게요.
이 테스트는 객체생성시 str
으로 잘 출력되는지 확인하기 위함이에요.
from django.test import TestCase
from django.contrib.auth import get_user_model
from core import models
def sample_user(email='test1@testtest.com', password='testpass'):
"""Create a sample user"""
return get_user_model().objects.create_user(email, password)
# 클래스 밖에서 함수를 생성해 둠으로써 클래스 안에서 호출시 메서드 호출만으로도 자유롭게 샘플 유저 객체생성이 가능
class ModelTests(TestCase):
def test_create_user_with_email_successful(self):
'''Test creating a new user with an email is successful'''
email = 'test@example.com'
password = 'testpassword123'
user = get_user_model().objects.create_user(
email=email,
password=password,
)
self.assertEqual(user.email, email)
self.assertTrue(user.check_password(password))
def test_new_user_email_normalized(self):
"""Test the email for a new user is normalized"""
email = 'test@EXAMPLE.COM'
user = get_user_model().objects.create_user(email, 'test123')
self.assertEqual(user.email, email.lower())
def test_new_user_invalid_email(self):
"""Test creating user with no email raises error"""
with self.assertRaises(ValueError): # value 에러를 발생시키지 않으면 테스트가 fail나요.
get_user_model().objects.create_user(None, 'test123')
def test_create_new_superuser(self):
"""Test creating a new superuser"""
user = get_user_model().objects.create_superuser(
'test@testtesttest.com',
'test123'
)
self.assertTrue(user.is_superuser) # is_superuser 필드는 PermissionMixin클래스에 있는 변수명이에요.
self.assertTrue(user.is_staff)
def test_tag_str(self):
"""Test the tag string representation"""
tag = models.Tag.objects.create(
user=sample_user(),
name='Vegan'
)
self.assertEqual(str(tag), tag.name)
여기까지 작성했다면 테스트를 돌려볼게요. 당연히 fail날거에요.
AttributeError: module'core.models' has no attribute 'Tag'
가장 아래에 Tag클래스를 만들게요.
여기서 눈여겨 볼만한 점은 User클래스를 다이렉트로 연결하지 않고 settings에 정의된 AUTH_USER_MODEL
을 사용해서 관계를 맺어주도록 할거에요.
구체적으로 왜? 이렇게 쓰는지 알고 싶다면 여기를 클릭해주세요.
그리고 장고 셋팅파일에서 뭔가를 꺼내올때 쓰기 위한 임포트를 해야하는데요.
django.conf
를 이용할게요.
from django.conf import settings
...
...
...
class Tag(models.Model):
"""Tag to be used for a recipe"""
name = models.CharField(max_length=255)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
def __str__(self):
return self.name
관리자 페이지에 등록할게요.
admin.py
...
...
admin.site.register(models.User, UserAdmin)
admin.site.register(models.Tag) # 왜 두번째 인자를 안넣냐고요? 기본값으로 제공되는 녀석을 사용할 거거든요.
아래 명령어를 실행하면 0002_tag.py
파일이 생성되요.
docker-compose run --rm app sh -c "python manage.py makemigrations"