TIL project - 6

이동근·2021년 2월 25일
2

Project

목록 보기
6/20

프로젝트 종료 D-1

여태까지 사용했던 코드와 주요한 내용들을 정리 해보려고 합니다.

쿼리스트링

url 주소를 보면 url.py에서 지정해준 경로 말고 뒤에 ?keyword=&endYn=ALL&order=recommend 적혀져 있는 것을 볼 수있는데 이 부분이 쿼리 스트링이다.
keyword= 검색
endYN= 전체, 진행중, 종료중으로 필요한 것만 보여준다.
order=recommend 상품을 특정한 순으로 정렬을 한다.
-> 3개의 쿼리스트링이 사용되고 있다고 알 수 있다.

우선! 쿼리스트링을 이해하기 위해서는 '가변객체' 라는 것을 알아야 한다.
가변객체란 할당된 값을 수정할 수 있는 객체를 의미한다.
이 개념을 생각한 후 쿼리스트링을 작성하는 법을 보게 되면

ProductlistQueryView class에서 get을 구현하려고 한다 프론트에서 받는 request에는 많은 정보가 담겨있을 것이다.
그 이후 코드에 request.GET.get 이있다.

이 코드의 의미는 request에 GET에 관련된 정보를 추가한다는 의미 이다. 이런 것이 가능한 이유는 request가 가변객체이기 때문이다. request가 가변객체이기 때문에 request에 담긴 정보에 quey문으로 추가로 보내는 정보를 담을 수 있게 되는 것이다. 그리고 그 정보를 get으로 가져오게 되는 것이다.
(지금 GET이 반복이 되는데, def get은 http의 get이고, request.GET의 GET은 추가로 담긴 정보를 의미, 그리고 request.GET.get의 뒤쪽에 있는 'get'은 파이썬의 get이다. 각각 다 의미하는 get의 내용이 다르다. 헷갈리지 말자)

이런식으로 category, endYN, order_condition과 관련된 세개의 쿼리 스트링을 받는 것이다.

http -v get 127.0.0.1:8000/product/main category==1 endYN==2 order==support

endYN = 1(기본값), 2(진행중), 3(마감)
order = recommend(추천순), price(펀딩액순), support(응원참여자순)

그럼 정렬과, 필터를 적용해서 성공을 한 url은 이렇게 나오게 된다.

GET /product/main/query?category=8&endYN=2&order=support

이런식으로 나오게된다!!

Q객체

여러개의 조건이 있을때 Q()를 사용하면 코드를 더욱 간결하고 쉽게 사용할 수 있다.
주의할점!
Q객체를 사용하기 위해서는 'django.db.models import Q'를 적어줘서 Q를 임포트 한 뒤에 사용한다.

Q를 사용한 코드이다.

왜 사용을 했는가, 쿼리파라미터로 받는 endYN의 값이 조건에 따라서 달라지기 때문에 사용했다.

원래라면

if endYN ==2:
    products = Product.objects.filter(closing_date__lte=datetime.today())
    
if endYN ==3:
    products = Product.objects.filter(closing_date__gt=datetime.today())

이런식으로 진행이 되어야 한다.

만약 q를 사용한다면

q = Q()
if endYN =='2':
    q &= Q(closing_date__lte=datetime.today())

if endYN =='3':
    q &= Q(closint_date__lte=datetime.today())
    
products = Product.objects.filter(q)

이런식으로 적어주면 된다.
Q객체를 사용하는데 있어 프론트 정민님과 합의된 사항으로 진행중은 '2', 마감된 펀딩은 '3' 으로 하려고 했다. 그래서 당연히 intger 형태인 줄 알았다. django shell을 입력하면 나오는데, Views.py에서 적을 때에는 q에 추가가 되지 않기 때문이다. 기억하자 쿼리스트링은 문자형으로 온다.!!

https://brownbears.tistory.com/425?category=168282 -불곰 Q객체 사용법

filter_prerixes

filter_prefixes
filter_prefixes = {
        'category' : 'category__id__in',
        'endYN' :  'Product__closing_date__lte=datetime.today()',
        }
filter_set = {
        filter_prefixes.get(key) : value for (key, value) in dict(request.GET).items() if filter_prefixes.get(key)
        }
products = Product.objects.filter(**filter_set).distinct()

위에서 사용한 Q객체와 같이 반복되는 if문을 줄이기 위해 사용되는 방법이다.

쿼리스트링으로 받는 category와 endYN을 dict의 형태로 만들어서 담는다.
'category : categroyidin': '__in'은 주어진 리스트안에 존재하는 데이터 검색
즉 카테고리에있는 id 값을 모두 가져온다는 의미이다.

'endYN : Productclosing_datelte=datetime.today()
__lte는 '=' ~보다 작다는 뜻 즉 datetime.today()= 오늘 날짜, 오늘 보다 더 작은 날짜들을 가져오게 된다.

dict에 있는 값들을 우리가 원하는 대로 빼줘서 filter_set 원하는 filter조건들을 넣어주는 작업이 필요하다.
filter_set = {
filter_prefixes.get(key) : value for (key, value) in dict(request.GET).items() if filter_prefixes.get(key)}

for (key, value) in dict(request.GET).items() : request.GET으로 받은 쿼리스트링을 itmes 메소드로 key와 value를 묶어준다음 각각 key값과 value 값으로 만들어 준다.

filter_prefixes.get(key) : value : key와 value를 우리가 원하는 형태로 dict로 만들어 주는 작업을 해준다.

Product.objects.filter(filter_set).distinct()
: '
filter_set'은 **kwarg 이다. 그래서 정해진 값이 없이 위에서 여러개의 필터를 건 내용으로 바꿔 filter를 실행해 준다.

근데!!
filter-prefixe가 좋은 방법은 아니다 우리에겐 Q라는 좋은 방법이 있기때문이다.
조건을 and와 or로 설정해서 여러 조건들을 설정하는 방법으로는 filter_prefex 보단 Q가 더 좋으니까 Q를 더욱 사용하면 된다.!!

시간계산

이번 project를 하면서 어려웠던 점 중 하나인 시간계산이다. 파이썬을 사용해서는 우리가 원하는 값을 얻을 수 있지만 django에서는 안됬다.
파이썬

안되는 이유!
django에서 시간계산이 안되는 이유를 'timezone' 문제라고 한다.

datetime.datetime.now(), datetime.datetime.today() 등으로 현재 날짜/시간을 가져오는 경우 TIME_ZONE 설정에 따라 +9 기준의 값이 나오지만 TIME_ZONE 정보가 없는 naive datetime 객체이다.

즉 다시 말해서 datetime.datetime.now()는 실행환경의 시간대에 따라서 시각을 표시한다. 그래서 이를 해결하기 위해서는 settings.py의 USE_TZ = True 를 false로 변경해주면된다.

장고 내부적으로 인식하는 시간대 사용
USE_TZ = True
local time을 사용
USE_TZ = False

시간에 관련해서는 추후에 따로 포스팅 하려고 합니다.!!


profile
하루하루 1cm 자라는 개발자

1개의 댓글

comment-user-thumbnail
2021년 2월 28일

오호 request가 가변객체인 걸 슬쩍 듣고 넘어갔는데 잘 공부하고 갑니다.

답글 달기