First things first , I'ma say all the words inside my head
먼저, 내 머릿속에 있는 것들을 모두 말할 거야
[ Imagine Dragons, "Believer" ]
뒤돌아 본 2021년은 마지막 분기를 제외하고는 전혀 밝지 않았고 형태마저 희미했다. 1분기는 실패의 늪이었고, 2분기와 3분기는 우울을 핑계 삼은 좌절과 나태의 수렁이었다. 마지막 분기에 이르러서야 자리에서 일어났고, 도전이라는 목표 아래 노력과 체력을 불살랐다. 주말 아침부터 감상에 젖어드는 이유는 사실 별거 없다. 새 해가 시작되었을 뿐이다.
어제에 이어서 마지막 3번 과제를 해결하고, 추가로 주말용 과제로 덧붙여 주신 views.py
추가 구현을 해보기로 했다. 주말에는 회사를 나가지 않았으니, 회사에 대한 이야기는 없다.
3. customer 검색했을때 내가 방문한 매장 - 언제 방문했는지
일단 요청받은 정보는 두가지이다. 방문했던 매장과, 방문 시간. 매장의 이름은 Shop table에 있고, 방문 시간과 shop_id, customer_id는 Visited table에 있으며, 받아올 data는 Customer. Customer의 id로 data 들을 찾아 와야 하겠다.
(위는 생략)
shops_name = [customer.shop.name for customer in data.visited_set.all()]
visited_time = [visitor.visited_time for visitor in data.visited_set.all()]
return shops_name, visited_time
request
를 통해 데이터를 받아오던 Pure Django 때와는 다르게 DRF에서 ModelViewSet
을 지나 얻게 되는 데이터의 type
은 list
나 dict
에 담기지 않은 객체 그 자체이다. 해서, data.id
or data.table_set.all()
과 같은 문법이 가능해 진다. 하지만 serializer
로 넘어온 데이터는 해당 연산에서 저장되지 않는다고 사수님이 덧붙이셨는데, 아직 제대로 이해가 되지는 않았다. 쨌든, 다시 돌아가서 이번에는 중복 데이터도 필요하므로 .set()
은 제외했다. 리스트가 따로 따로 나왔는데, 왠지 하나로 합칠 수 있을 것 같아서 자주 쓰던 방법을 적용해봤다.
results = [{'id' : i.id,
'shop_id' : i.shop_id,
'visited_time' : i.visited_time,
'customer_id' : i.customer_id} for i in data.visited_set.all()]
return results
프로젝트를 하면서 여러번 보아온 dict
형태로 데이터 담기. 앞선 과제에서 보았듯이, data.visited_set.all()
로 Visited table의 데이터를 긁어와 붙힌 다음, for loop
로 원하는 데이터를 원하는 모양으로 담고 list comprehension
으로 깔끔히 정돈.(뿌듯)
for loop
는 쓰면 쓸수록 연산 속도(로딩 속도)가 느려진다. 그래서 사수님도 for loop
는 생각보다 자주 쓰지 않는다고 말씀하셨다. 주말 저녁(토요일 저녁 8시..)이었지만, 과제에 대한 질문에 사수님은 정성껏 답변 해주셨다. 내가 짠 코드는 맞았고, 의도한 대로 결과값이 출력되었다. 그리고 사수님은 한 줄로 된 코드를 보여주셨다.
return Visited.objects.filter(customer_id = data.id).values()
오.. .values()
는 첫 날 들었는데, 그새 까먹었다. 다만, 위와 같이 데이터를 보냈을 시, 프론트의 부담이 가중 될 수 있기 때문에, 필요한 key 값만 골라서 출력해주면 프론트와 사이좋게 지낼 수 있을 것이다 라고 사수님이 조언하셨다.
1) exact : 일치하는 조건을 입력할 때 사용
Menu.objects.filter(name__excact='커피')
Menu.objects.filter(name__iexcact='커피')
※ iexact는 대소문자를 가리지 않고 일치하는 조건
2) contains : 부분 일치 조건 입력할 때 사용
Menu.objects.filter(name__contains='cof')
Menu.objects.filter(name__icontains='CofF')
※ icontains는 대소문자를 가리지 않고 부분 일치하는 조건
3) in : 여러 조건을 포함할 경우 사용
Menu.objects.filter(name__in=['커피','쿠키'])
4) gt / lt / gte / lte
gt (greater than) : >
lt (less than) : <
gte (greater than or equal) : >=
lte (less than or equal) : <=
Menu.objects.filter(price__gt=price(100.00)
5) startswith / endswith
startswith : 조건으로 시작하는 문자열 검색
endswith : 조건으로 끝나는 문자열 검색
Menu.objects.filter(name__startswith='c')
6) union()
두 개 이상의 쿼리셋 변수를 하나의 쿼리셋 값으로 합친다.
data1 = Menu.objects.filter(name__exact='커피')
data2 = Menu.objects.filter(name__exact='쿠키')
data3 = union(data1, data2)
7) intersection()
교집합으로 두 개 이상의 쿼리셋 변수 중 중복된 값을 가지고 온다.
data1 = Menu.objects.filter(name__in=['커피', '라떼'])
data2 = Menu.objects.filter(name__in=['커피', '밀크티'])
data3 = intersection(data1, data2)
결과는 name
이 커피
인 데이터를 가지고 온다.
I'm the one at the sail, I'm the master of my sea.
나는 항해중인 사람이고, 내 바다의 주인은 나야.
[ Imagin Dragons, "Believer" ]