1. 혼자 만들어보는 Zara - 권한에 따른 상품 추가

Kiyong Lee·2021년 12월 8일
0

개인프로젝트

목록 보기
5/9

혼자 만들어보는 Zara - 권한에 따른 상품 추가


1. views.py

class ProductView(View) :
    @login_required
    def post(self, request) :
        try :
            with transaction.atomic() :
                if request.user.role_id != RoleID.ADMIN.value :
                    return JsonResponse({'message' : 'PERMISSION_DENIED'}, status=403)
            
                data = json.loads(request.body)
                
                category_id = data['category_id']
                name        = data['name']
                price       = data['price']
                url         = data['url']
            
                product = Product.objects.create(
                    category_id = category_id,
                    name        = name,
                    price       = price
                )
                
                Thumbnail.objects.create(
                    product = product,
                    url     = url
                )
                
                return JsonResponse({'message' : 'SUCCESS'}, status=201)

        except KeyError :
            return JsonResponse({'message' : 'KEY_ERROR'}, status=400)
        
        except IntegrityError :
            return JsonResponse({'message' : 'INTEGRITY_ERROR'}, status=400)

토큰을 통해 유저정보를 가져온 뒤, 유저의 등급을 불러옵니다.

유저가 관리자면 상품을 추가할 수 있는데, 일반 유저면 403 PermissionDenied
발생합니다.

그리고 상품추가후 상품의 썸네일 이미지를 추가하는데, 두 개의 테이블이 다르다보니
트랜잭션의 원자성을 지켜야 했습니다.

with transaction.atomic() 선언을 맨 처음에는 데이터 저장할 때 하려했는데
데이터를 불러오고 저장하는 과정에서 데이터를 바꿀 수 있는 문제가 있어서
데이터를 가져오는 순간에 설정해야 한다는 조언을 들었습니다.

그래서 트랜잭션을 제일 먼저 설정해줬고, 상품생성 후 썸네일생성하도록 작성했습니다.


2. Unit Test


로그인 Unit Test때처럼 global 변수를 이용해서 코드 간소화를 했습니다.

class TestProductView(TransactionTestCase) :
    def setUp(self) :  
        role1     = Role.objects.create(id=1, role='admin')
        role2     = Role.objects.create(id=2, role='user')
        
        admin     = User.objects.create(id=1, email='test1', password='1234', role=role1)
        user      = User.objects.create(id=2, email='test2', password='1234', role=role2)
        
        access_token1 = jwt.encode({'id' : admin.id}, settings.SECRET_KEY, settings.ALGORITHMS)
        access_token2 = jwt.encode({'id' : user.id}, settings.SECRET_KEY, settings.ALGORITHMS)
        
        global headers1, headers2
        headers1 = {'HTTP_Authorization' : access_token1}
        headers2 = {'HTTP_Authorization' : access_token2}

유저의 권한을 식별하기 위해 토큰이 필요한데, 초기값 세팅하는 setUp에서
global 변수로 설정했습니다.

    def test_success_post_product(self) :
        client = Client()
        
        product = {
            'category_id' : 1,
            'name'        : 'hihi',
            'price'       : 22222,
            'url'         : 'url'
        }
        
        response = client.post('/products', json.dumps(product), content_type='application/json'
                                ,**headers1)
        
        self.assertEqual(response.status_code, 201)
        self.assertEqual(response.json(), {
            'message': 'SUCCESS'
        })

client를 이용해 요청을 보낼 때 Keyword Argumentheaders1을 담아 보냅니다.

초기값 세팅에 global설정을 안했으면 테스트할때마다 설정했어야 하는데
설정해줌으로서 간편하게 사용할 수 있었습니다.

profile
ISTJ인 K-개발자

0개의 댓글

관련 채용 정보