[drf | recipe] Build a Backend REST API - 29

Hyeseong·2021년 3월 6일
0
post-custom-banner

Create a new app🏎

docker-compose 명령어🚵‍♀

도커 명령어 한줄로 장고 앱을 하나 만들어 줄게요.

docker-compose run --rm app sh -c "python manage.py startapp recipe"

settings.py & directory🚴‍♀

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',
]

test 작성🏋‍♀

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'

model 작성⛹‍♀

가장 아래에 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 🏊‍♀

관리자 페이지에 등록할게요.
admin.py


...
...

admin.site.register(models.User, UserAdmin)
admin.site.register(models.Tag) # 왜 두번째 인자를 안넣냐고요? 기본값으로 제공되는 녀석을 사용할 거거든요.

migration

아래 명령어를 실행하면 0002_tag.py 파일이 생성되요.

docker-compose run --rm app sh -c "python manage.py makemigrations"

profile
어제보다 오늘 그리고 오늘 보다 내일...
post-custom-banner

0개의 댓글