[ORM]OR 조건으로 데이터 분류

박민하·2022년 7월 5일
0

DJANGO

목록 보기
16/22
post-thumbnail

왓챠피디아 클론 코딩에서 따온 코드


from django.http      import JsonResponse
from django.views     import View
from django.db.models import Q

from films.models import Film

class FilmView(View):
    def get(self, request):
        try:
            genre            = request.GET.get('genre', None)
            country          = request.GET.get('country', None)
            running_time_min = request.GET.get('time', None)

            sort   = request.GET.get('sort')
            offset = int(request.GET.get('offset', 0))
            limit  = int(request.GET.get('limit', 10))

            q = Q()

            if genre:
                q &= Q(genres__name = genre)

            if country:
                q &= Q(countries__name = country)

            if running_time_min:
                q &= Q(running_time_min__lte = int(running_time_min))

            sort_set = {
                'random'          : '?',
                'score'           : 'rate_set__score',
                'time-ascending'  : 'running_time_min',
                'time-descending' : '-running_time_min',
            }

            order_key = sort_set.get(sort, 'id')

            films = Film.objects.filter(q).order_by(order_key)[offset:offset+limit]

            results = [{
                    'id'               : film.id,
                    'name'             : film.name,
                    'release_date'     : film.release_date.year,
                    'image_url'        : film.image_url,
                    'country'          : [country.name for country in film.countries.all()],
                    'running_time_min' : film.running_time_min,
                } for film in films]
            return JsonResponse({'results' : results}, status = 200)
        except KeyError:
            return JsonResponse({'message' : 'KEY_ERROR'}, status = 400)

request.GET.get('<key>', defalt = None)

  request.GET은 http request 정보를 dictionary 형태로 받을 수 있게 한다. key값에 해당되는 value 값을 불러오며, 만약 value가 없는 경우에는 None을 반환한다.

✔ request.GET.get('genre', None)

/films?genre=드라마&sort=random 경로를 요청하면, genre가 드라마인 value값을 랜덤으로 가져온다. 만약 value값이 없다면 아무것도 반환하지 않는다.

✅ 무한스크롤 기능

sort   = request.GET.get('sort')
offset = int(request.GET.get('offset', 0))
limit  = int(request.GET.get('limit', 10))

order_key = sort_set.get(sort, 'id')

films = Film.objects.filter(q).order_by(order_key)[offset:offset+limit]
  • offset : 시작 인덱스를 지정할 수 있다. 기본값은 0이다.
  • limit : 마지막 인덱스를 지정할 수 있다. 기본값은 10이다.

✔ /films?genre=드라마&offset=3

genre가 드라마인 value값을 3번째 인덱스부터 가져온다(0,1,2 인덱스 제외).

✔ /films?genre=드라마&offset=3&limit=12

genre가 드라마인 value값을 3~14번쩨 인덱스까지만 가져온다.

✔ [offset:offset+limit]로 한 이유?

  limit을 개수로 사용하기 위해서 이렇게 코드를 작성했다. 만약 [offset:limit]으로 쓴다면 &offset=3&limit=12의 영우 3~11번째 인덱스만 가져올 수 있다.

✅ 사용한 django 메서드

✔ running_time_min__lte

  • lte : less than or equal 작거나 같은 값
  • lt : less than 작은 값
  • gte : greater than or equal 크거나 같은 값
  • gt : greater than 큰 값

✔ '?'

  • 'random' : '?'
  • 랜덤

✅ Q객체

✔ q &= Q(running_time_min__lte = int(running_time_min))

  기본적으로 str값으로 가져오기 때문에 숫자를 비교하려면 int로 변경해야 한다.

profile
backend developer 🐌

0개의 댓글