📘 DRF 


사전 준비하기

  • products앱을 만들고 product 모델을 만들어주세요.
  • product 모델에는 name , price , quantity , category필드가 있습니다.
    • 각 필드는 적절한 형태의 필드를 사용해 주세요.
    • category는 아래 선택지 중 하나가 적용되도록 작성해 주세요
CATEGORY_CHOICES = (
    ("F", "Fruit"),
    ("V", "Vegetable"),
    ("M", "Meat"),
    ("O", "Other"),
)
  • migrate 이후 seed를 사용해서 랜덤 한 데이터를 30개 만들어주세요.

 

↓ 해보자

1. products app 생성하기

더보기
python manage.py stratapp products

 

api_pjt/settings.py
'products',

2. product Model 만들기

더보기
from django.db import models

class Product(models.Model):
    CATEGORY_CHOICES = (
    ("F", "Fruit"), # 한 글자는 DB에 저장, 단어는 사용자에게 보여질 단어
    ("V", "Vegetable"),
    ("M", "Meat"),
    ("O", "Other"),
    )
    name = models.CharField(max_length=30)
    price = models.PositiveIntegerField() # 정수값만
    quantity = models.PositiveIntegerField()
    category = models.CharField(max_length=1, choices=CATEGORY_CHOICES)

    def __str__(self):
        return self.name

3. migrate

더보기
python manage.py makemigrations
python manage.py migrate

4. 🌱 랜덤 한 데이터 30개 만들기

더보기
python manage.py seed products --number=30

더 복잡한 쿼리 사용하기

  • 기본적인 ORM 외에도 다양한 비즈니스 상황에 맞는 쿼리가 필요하다.
  • Django의 ORM은 대부분의 쿼리가 가능하도록 설계되어 있다.
  • 값을 가져와서 Python으로 조작해도 되지만 Database에서 조작한 후 가져오는 것이 필요한 경우가 있다.

Q()를 이용해서 여러 조건 연결하기

  • 여러 조건에 해당하는 ORM이 필요하다면 Q 객체를 사용한다.
  • Q는 조건을 정의하는 객체이다.
    • 논리적 OR 조건을 만들거나 여러 개의 조건을 결합해서 SQL의 WHERE 절에 해당하는 기능을 온전히 활용할 수 있다.
      • & : and
      • | : or
      • ~ : not 
예제 1)
가격이 15000보다 크거나 수량이 3000보다 적은 제품들을 조회해 보세요.

정답 1) |
Product.objects.filter(
	Q(price__gt=15000) | Q(quantity__lt=3000)
)


결과)

 

예제 2)
가격이 10000보다 크고 수량이 2000보다 적은 제품들을 조회해 보세요.

정답 2) &
Product.objects.filter(
	Q(price__gt=10000) & Q(quantity__lt=2000)
)


결과)


조건에 해당되는 데이터가 없대요

F() 를 이용해서 필드값 가져오기

  • F()는 쿼리를 작성할 때 이전의 필드 값에 의존하는 작업을 쉽게 할 수 있다.
  • 주로 필드의 값을 가져오거나 업데이트해서 값을 참조하는 데 사용한다.
  • python 메모리로 값을 가져오지 않고 필요한 작업을 데이터베이스에서 수행할 수 있다.
예제 3)
모든 프로덕트의 가격을 1000원 인상해 보세요.

정답 3)
Product.objects.update(price = F('price') + 1000)​


결과)

더보기


30개의 price에 1,000을 인상하였어요

반영 전
반영 후

annotate()를 사용해서 추가 정보 제공하기

🔗 공식 문서

  • annotate == 주석을 달다
  • 조회하는 쿼리셋 각각에 추가적인 정보(데이터)를 제공하는 데 사용한다.
예제 4)
각 프로덕트 별 total_price를 추가로 구성해서 조회해 주세요.
(total_price=price*quantity)

정답 4)
products = Product.objects.annotate(
    total_price=F('price') * F('quantity')
)


👍🏻 objects. 와 annotate() 사이에 filter(), Q(), F()를 입력할 수 있어요.
(all()은 생략하는 경우가 다반수예요)

결과)


DB에는 total_price가 칼럼으로 추가되진 않아요
조회하면서 계산될 뿐이에요


aggregate()를 사용해서 쿼리 하기

🔗 공식 문서

  • aggregate == 종합/집약하다
  • 조회하는 쿼리셋 전체에 대해 결과를 집계/집약한다.
  • 주로 집계 함수(Avg, Sum, Count 등)와 많이 사용한다.
예제 5)
전체 프로덕트의 평균 가격을 구하세요.

정답 5)
Product.objects.aggregate(Avg('price'))

# 이름 지어주기
Product.objects.aggregate(my_avg = Avg('price'))


결과)

더보기

 


이렇게 결괏값 명도 바꿀 수 있어요 "my_avg"

예제 6)
각 카테고리별 상품수를 구하세요.

정답 6)
Product.objects.aggregate(Count('category'))​

결과
{'category__count': 30}


이건 카테고리가 30개라는 뜻이다,,

 

Group By 적용하기

(Recommend) Django에서 Group By는 아래의 두 단계를 이용해서 수행한다.

  • values() 원하는 칼럼만 뽑은 다음
products.values('category')


결과)

<QuerySet [{'category': 'M'}, {'category': 'O'}, 
{'category': 'V'}, {'category': 'M'}, ...
{'category': 'F'}, '...(remaining elements truncated)...']>

 

 

  • annotate()로 묶어서 Group By를 수행
products.values('category').annotate(category_count = Count('category'))


결과)

{'category': 'F', 'category__count': 9}, 
{'category': 'M', 'category__count': 5}, 
{'category': 'O', 'category__count': 10}, 
{'category': 'V', 'category__count': 6}

+ Recent posts