https://github.com/sdoram/b4_exhibitions_backend
filter에서 or가 필요함
1. django Q 사용
from django.db.models import Q
장점 : django를 잘 이해하고 있다면 코드의 가독성이 크게 증가할 것 같음
단점 : 이해도가 높지 않다면 가독성에 악영향 끼칠 가능성 있음
결론 : 현재 프로젝트 구조상 중복해서 사용할 가능성이 높지 않으므로 | 를 통해서 처리하는 게 좋을 것 같다.
여러 모델의 filter 결과를 하나의 return에서 보여줘야 함
2. 전용 serializer 선언하기
장점 : views에서 가독성 증가
단점 : serializer 구성을 위한 시간 소요
결론 : 차후 수정의 여지가 있지만 지금은 views에서 처리하자.
1. return에 여러 모델의 filter 결과를 보여주기
문제점
return에 여러 모델의 filter 결과를 보여줘야 함
시도해 본 것들
exhibitions = Exhibition.objects.all()
reviews = Review.objects.all()
accompanies = Accompany.objects.all()
results = (
ExhibitionSerializer(exhibitions, many=True),
ReviewSerializer(reviews, many=True),
AccompanySerializer(accompanies, many=True),
)
return Response([result.data for result in results], status=status.HTTP_200_OK)
filter 없이 각각의 models를 불러오고 Response에서 한 번에 확인하기가 가능한 것을 확인했다.
filter에 or 조건 걸기
from django.db.models import Q 사용하기
exhibitions = Exhibition.objects.filter(
Q(content__icontains=search) | Q(info_name__icontains=search)
).order_by("-created_at")
조건을 중복해서 설정하고 싶을 때 Q를 통해서 사용할 수 있다.
Q 없이 구현하기
exhibitions = Exhibition.objects.filter(
content__icontains=search
) | Exhibition.objects.filter(info_name__icontains=search).order_by(
"-created_at"
)
여러 field를 거친다면 코드가 길어지겠지만, 아직 2개의 field만 확인하고 이 코드 말고 다른 곳에서 Q를 사용할 곳이 없기 때문에 | 를 통해서 or 조건 설정
해결 방법
class ExhibitionSearchView(APIView):
def get(self, request):
search = request.query_params.get("search", None)
# 키워드가 있는 경우
if search:
# 전시회 내용 or 제목으로 검색
exhibitions = Exhibition.objects.filter(
content__icontains=search
) | Exhibition.objects.filter(info_name__icontains=search).order_by(
"-created_at"
)
reviews = Review.objects.filter(content__icontains=search).order_by(
"-created_at"
)
accompanies = Accompany.objects.filter(content__icontains=search).order_by(
"-created_at"
)
else:
exhibitions = Exhibition.objects.all().order_by("-created_at")
reviews = Review.objects.all().order_by("-created_at")
accompanies = Accompany.objects.all().order_by("-created_at")
results = (
ExhibitionSerializer(exhibitions, many=True),
ReviewSerializer(reviews, many=True),
AccompanySerializer(accompanies, many=True),
)
# serializer.data의 리스트를 Response로 보내주기
return Response([result.data for result in results], status=status.HTTP_200_OK)
알게 된 점
Response에 담을 수 있는 정보는 꽤 유연한 것 같다.
2. 검색 결과에 pagination 기능 추가
문제점
class ExhibitionSearchView(APIView):
def get(self, request):
search = request.query_params.get("search", None)
pagination = CustomPageNumberPagination()
# 키워드가 있는 경우
if search:
# 전시회 내용 or 제목으로 검색
exhibitions = Exhibition.objects.filter(
content__icontains=search
) | Exhibition.objects.filter(info_name__icontains=search).order_by(
"-created_at"
)
reviews = Review.objects.filter(content__icontains=search).order_by(
"-created_at"
)
accompanies = Accompany.objects.filter(content__icontains=search).order_by(
"-created_at"
)
else:
exhibitions = Exhibition.objects.all().order_by("-created_at")
reviews = Review.objects.all().order_by("-created_at")
accompanies = Accompany.objects.all().order_by("-created_at")
paginated_exhibitions = pagination.paginate_queryset(exhibitions, request)
paginated_reviews = pagination.paginate_queryset(reviews, request)
paginated_accompanies = pagination.paginate_queryset(accompanies, request)
results = (
ExhibitionSerializer(paginated_exhibitions, many=True),
ReviewSerializer(paginated_reviews, many=True),
AccompanySerializer(paginated_accompanies, many=True),
)
# serializer.data의 리스트를 Response로 보내주기
return Response(
[pagination.get_paginated_response(result.data) for result in results],
status=status.HTTP_200_OK,
)
pagination을 검색 결과에도 확인할 수 있도록 만들었지만, 각 검색 별로 독립적이지 않아서 하나의 페이지를 넘길 때 다른 검색 결과의 페이지도 넘어가는 형태가 됐다.
하나의 view로 검색을 처리하되 중간에 검색 조건을 추가로 설정해서 하나의 model만 검색할 수 있도록 변경하는 게 좋을 것 같다.
'프로젝트 > 미술관 뒤 백엔드 지금은 전시상황' 카테고리의 다른 글
최종 팀 프로젝트[front] content-type 정하기 (0) | 2023.06.20 |
---|---|
최종 팀 프로젝트[front] API function 분리하기 (0) | 2023.06.14 |
최종 팀 프로젝트[back] 상세보기 pagination (0) | 2023.06.12 |
최종 팀 프로젝트[front] navbar (0) | 2023.06.09 |
최종 팀 프로젝트[back] drf_pagination (0) | 2023.06.08 |