-
list comprehension 중복 제거 - Object of type set is not JSON serializablePython 2022. 1. 16. 14:56
class ProductListView(View): def get(self, request, *args, **kwargs): tagcategory = request.GET.get('tagcategory', None) tag = request.GET.get('tag', None) user_type = request.GET.get('user_type', None) q = Q() if user_type: q &= Q(user__user_type__name=user_type) if tagcategory: q &= Q(producttag__tag__tag_category__name=tagcategory) if tag: q &= Q(producttag__tag__name=tag) products = Product.objects.filter(q) results = [ { 'user' : product.user.nickname, 'product_id' : product.id, 'product_name' : product.name, 'main_image' : product.main_image.image_url, 'tag_category_name': [tag.tag_category.name for tag in product.tags.all()], 'tag_name' : [tag.name for tag in product.tags.all() if tag.tag_category.name == tagcategory], 'created_date' : product.created_at.strftime('%Y년 %m월 %d일'), 'user_type' : product.user.user_type.name, } for product in products ] print(results) print(products.count()) return JsonResponse({'results': results}, status=200)
제품 리스트 페이지의 필터링 기능을 구현하고 있었습니다.
그 과정 중에 위의 results 안에서 'tag_category_name'을 가져올 때 겪었던 어려움에 대해 얘기하려고 합니다.
tag_category_name에는 '대륙', '지역', '테마', '인원'이라는 값이 들어있습니다.
1. 값이 중복되는 점 (ex - ['지역', '테마', '테마', '테마', '테마', '인원', '인원'])
2. [tag.name for tag in product.tags.all() if tag.tag_category.name not in ...]
- 이런 식으로 if문을 사용하고 싶었으나 list comprehension에 대한 이해가 부족한 것인지
아니면 방법이 없는 것인지 적절한 비교 대상을 선정하지 못했습니다.
3. set([tag.name for tag in product.tags.all())
- set을 통해서 중복을 제거하고자 했습니다. 그런데...
"Object of type set is not JSON serializable" 이런 에러 메시지가 떴습니다...
이 메시지를 처음 봤을 때 list comprehension을 set으로 바꾸는 과정에서 문제가 발생한 것이라고
지레 판단한 것이 아쉬운 결정이었습니다.
4. 사실 문제는 마지막인 JsonResponse({'results': results}) 에서 발생한 것이었습니다.
그래서 찾아보니 Python의 데이터를 JSON화 할 때 데이터 타입이 'set'이어서 생기는 문제라고 생각했습니다.
배열의 형태로 전달하려고 했으니 set을 리스트로 감싸서 보내면 되지 않을까라는 생각에
갑자기 기대감이 막 생기기 시작했고 바로 시도해봤습니다.
다행히!! 데이터의 중복 없이 잘 나오는 것을 확인할 수 있었습니다.
Python과 JSON의 데이터가 어떤 타입으로 포맷이 이뤄지는지 궁금하시다면
아래의 블로그에 아주 자세하게 정리되어 있으니 보신다면 많은 도움이 되리라 생각합니다.
https://rfriend.tistory.com/474
'Python' 카테고리의 다른 글
날짜 입력 및 D-Day 계산 (0) 2022.04.12 Python shell - help 기능 (0) 2022.01.16 UUID vs CharField의 max_length (0) 2022.01.02 Python dictionary get 메소드 vs Django objects get 메소드 (0) 2022.01.02 Python 용어 정리 (0) 2021.12.15