Project : WASH Korea [API]제품리스트 (1)
위코드 1차 프로젝트
[API] 제품리스트
멘토님의 팁 !
어떻게 시작해야할지 감이 안잡힌다면
- 모든 상품 정보를 GET 해오는 코드 작성
- 필터링 으로 원하는 부분만 GET 해오는 코드 작성
- 쿼리파라미터로 필터링 처리
+ Q객체 사용법
순으로 작성해보면 쉬울 것이라고 하셨다
멘토님의 팁 !
어떻게 시작해야할지 감이 안잡힌다면
- 모든 상품 정보를 GET 해오는 코드 작성
- 필터링 으로 원하는 부분만 GET 해오는 코드 작성
- 쿼리파라미터로 필터링 처리
+Q객체 사용법
순으로 작성해보면 쉬울 것이라고 하셨다

필요한 정보
: 제품 이미지, 태그, 이름, 서브이름, 가격 + 제품 id !
1. 전체 상품 정보를 GET
class ProductListView(View):
def get(self, request):
results = [{
"id" : product.id,
"name" : product.name,
"sub_name" : product.sub_name,
"price" : int(product.price),
"tags" : [tag.name for tag in product.tags.all()],
"product_image" : product.images.first().url
} for product in Product.objects.all()]
return JsonResponse({'results' : results}, status = 200)
tags와 image는 둘 다 one to many 관계지만 현재 페이지에서 tags는 모든 내용이 필요한 반면, image는 메인 이미지 한 장만 있으면 되기에 서로 다른 방법을 사용했다
또한 여기서 product.images.first().url 역참조 관계인 Product에서 ProductImage를 정참조처럼 불러올 수 있는 이유는 related name 을 사용했기 때문이다
# products/models.py
class ProductImage(models.Model):
url = models.CharField(max_length=2000)
product = models.ForeignKey('Product', on_delete=models.CASCADE, related_name='images')
class Meta:
db_table = 'product_images'
처음에는 for문을 사용해서 작성했지만 리스트 컴프리헨션을 사용하니 훨씬 깔끔해진 코드를 볼 수 있다
2. 필터링 사용
class ProductListView(View):
def get(self, request):
results = [{
"id" : product.id,
"name" : product.name,
"sub_name" : product.sub_name,
"price" : int(product.price),
"tags" : [tag.name for tag in product.tags.all()],
"product_image" : product.images.first().url
} for product in Product.objects.filter(sub_category_id = 1)]
return JsonResponse({'results' : results}, status = 200)
.filter 메소드를 사용해서 서브카테고리 1번에 해당하는 제품만 불러올 수 있게 변경해 주었다
쿼리파라미터 / 패스파라미터
쿼리파라미터를 이용하기 전에 어떤 개념인지 먼저 알아보자
1. 쿼리파라미터
주로 데이터를 특정 조건으로 검색하거나 정렬하고자 할 때 활용되는 방식
Query Parameter으로 전송된 API에 대응하기 위해서 URL 패턴 정의를 따로 해주어야 하는 부분은 없다
대신 View 함수에서 해당 Parameter에 접근하기 위해서는 HTTP Method에 따라 request.GET 또는 request.POST로 QueryDict 객체를 호출해야 한다
QueryDict 객체는 Dictionary의 subclass로 key와 value형식으로 이루어져 있기 때문에, 전달되는 변수를 키값으로 조회해서 데이터를 처리하면 된다
2. 패스파라미터
커머스 사이트의 제품 상세 페이지에 대한 정보를 요청할 때 자주 사용
장고에서 Path Variable로 리소스에 대한 정보를 받아서 처리하기 위해서는 <>기호를 통해서 urlpattern을 정의해야 한다
3. 쿼리파라미터로 필터링
class ProductListView(View):
def get(self, request):
category = request.GET['category']
sub_category = request.GET.get('sub_category')
if category:
Products = Product.objects.filter(sub_category_id__category_id = category)
if sub_category:
Products = Product.objects.filter(sub_category_id = sub_category)
results = [{
"id" : product.id,
"name" : product.name,
"sub_name" : product.sub_name,
"price" : int(product.price),
"tags" : [tag.name for tag in product.tags.all()],
"product_image" : product.images.first().url
} for product in Products]
return JsonResponse({'results' : results}, status = 200)
카테고리와 서브카테고리로 각각 필터링을 주었다
여기서 category = request.GET['category'], sub_category = request.GET.get('sub_category')
두 가지 방법은 무엇이 다른 것일까 ?
답은 get() 메서드의 사용법에서 찾을 수 있다
get() 메서드는 키값이 딕셔너리 안에 있으면 밸류값을 리턴해주고 키값이 존재하지 않으면 디폴트값 None을 리턴한다 ( 물론 디폴트 값을 직접 정해줄 수 도 있다 )
따라서 현재 코드에선 category가 없으면 에러가 발생하고 sub_category는 없어도 된다 ( category 전체 제품 리스트 호출 )
러쉬코리아 홈페이지에서 확인을 해보면 카테고리별 전체 제품 보기는 있어도 러쉬의 모든 제품을 모든 페이지는 없기에 카테고리 코드는 category = request.GET['category'] 처럼 작성해서 항상 쿼리파라미터가 있도록 작성했다
4. 가격 순 정렬

제품리스트 페이지에는 다양한 정렬 기능이 존재한다
가격 높은 순, 낮은 순으로만 먼저 정렬 기능을 만들어 보자
쿼리파라미터에 price만 추가하면 된다
class ProductListView(View):
def get(self, request):
category = request.GET['category']
sub_category = request.GET.get('sub_category')
price = request.GET.get('price')
if category:
Products = Product.objects.filter(sub_category_id__category_id = category)
if sub_category:
Products = Product.objects.filter(sub_category_id = sub_category)
if price:
Products = Products.order_by(price)
results = [{
"id" : product.id,
"name" : product.name,
"sub_name" : product.sub_name,
"price" : int(product.price),
"tags" : [tag.name for tag in product.t정ags.all()],
"product_image" : product.images.first().url
} for product in Products]
return JsonResponse({'results' : results}, status = 200)
👏 멘토님 리뷰 👏
현재 방식으로 작성할 경우 정렬기능이 추가될 때 마다 계속 쿼리파라미터와
if문을 추가로 만들어줘야 한다정렬될 내용을 묶음으로 만드는 것이 훨씬 깔끔하게 보이고 스스로가 편하다
ex.
class ProductListView(View): def get(self, request): sorting = request.GET.get('sort', 'id') ... sort = { "id" : "id" "price" : "price", "-price" : "-price", }너무나 당연한 말이다 러쉬홈페이지만 봐도 추천을 기본 순으로 본다면 4개의 정렬이 만들어져야 한다
바로 반영해서 코드를 수정해 주었다
class ProductListView(View): def get(self, request): category = request.GET['category'] sub_category = request.GET.get('sub_category') sorting = request.GET.get('sort', 'id') if category: Products = Product.objects.filter(sub_category_id__category_id = category) if sub_category: Products = Product.objects.filter(sub_category_id = sub_category) sort = { "id" : "id", "price" : "price", "-price" : "-price", } results = [{ "id" : product.id, "name" : product.name, "sub_name" : product.sub_name, "price" : int(product.price), "tags" : [tag.name for tag in product.t정ags.all()], "product_image" : product.images.first().url } for product in Products] return JsonResponse({'results' : results}, status = 200)
그러면 Q객체 는 언제 쓰는 걸까 ???
다음 글에서 만나봅시다 !!!
Author And Source
이 문제에 관하여(Project : WASH Korea [API]제품리스트 (1)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@gyuls/Project-WASH-Korea-API제품리스트-1저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)