TIL#148 Q()

Dasom·2021년 7월 13일
0

Django

목록 보기
26/34

혼자 공부 겸 미니 프로젝트를 진행 중에 조건에 따라 filtering을 하게 되었는데 겹치는 조건들이 너무 많았다. 마침 지인분의 블로그를 보게 되었고, Q를 이용한 다른 방법도 있다는 것을 알게 되어 지저분하고 맘에 안들던 코드를 조금 더 깔끔하게 고칠 수 있게 되었다😀

도움이 된 지인분 블로그

# 처음 코드 

if date and date.date() == now.date():
    return self.queryset.filter(
        Q(started_at__gte=now) &
        Q(started_at__lt=next_date) &
        Q(movie_id__in=movie_ids) &
        Q(theater_screen__theater_id__in=theater_ids)
    ) if len(movie_ids) > 0 else self.queryset.filter(
        Q(started_at__gte=now) &
        Q(started_at__lt=next_date) &
        Q(theater_screen__theater_id__in=theater_ids)
    )
elif date and date.date() != now.date():
    return self.queryset.filter(
        Q(started_at__gte=date) &
        Q(started_at__lt=next_date) &
        Q(movie_id__in=movie_ids) &
        Q(theater_screen__theater_id__in=theater_ids)
    ) if len(movie_ids) > 0 else self.queryset.filter(
        Q(started_at__gte=date) &
        Q(started_at__lt=next_date) &
        Q(theater_screen__theater_id__in=theater_ids)
    )

코드를 보면 Q()안의 인자들이 중복이 되는 경우가 많아서 보기에 너무 지저분하다고 생각하던 참이었다.

# 이렇게 Q를 가지고 있는 변수를 하나 지정하여
q = Q()

# add를 사용하여 추가 할 수 있고 두번째 인자의 AND/OR 로 구분한다.
q.add(Q(started_at__gte=date), q.AND)
q.add(Q(started_at__gte=date), q.OR)

# 빈값으로 시작하지 않아도 된다.
q = Q(started_at__get=date)

q.add(Q(started_at__lte=next_date), q.AND)

조건이 한가지 더 필요했어서 코드가 더 지저분해지는 걸 생각하던 찰나에 좋은 방법을 알게 되었다.

# 수정 후 코드 

q = Q(started_at__lt=next_date)

if len(movie_ids) > 0 and len(theater_ids) == 0:
    q.add(Q(movie_id__in=movie_ids), q.AND)
elif len(movie_ids) == 0 and len(theater_ids) > 0:
    q.add(Q(theater_screen__theater_id__in=theater_ids), q.AND)
else:
    q.add(Q(movie_id__in=movie_ids), q.AND)
    q.add(Q(theater_screen__theater_id__in=theater_ids), q.AND)

if date and date.date() == now.date():
    q.add(Q(started_at__gte=now), q.AND)
elif date and date.date() != now.date():
    q.add(Q(started_at__gte=date), q.AND)

return self.queryset.filter(q)
profile
개발자꿈나무🌲

0개의 댓글