쉘 데이터 조회
처음에 장고를 할 때 shell을 피하고 Views 로 먼저 갔던 적이 있었다 정말 안좋은 습관이다 무조건 shell로 먼저 확인 후 적용시켜라 멘토님한테 정말 많이 혼났다 .. 힝..ㅠ 나두 쓰고 싶지만 어려븐디 어쪄ㅠ 안 혼나기 위해.. 연습했다
핵심. 프론트엔드 요청에 따라 다르겠지만 json형식으로 들어온 요청을 전달하려면 파이썬에서 비슷한 딕셔너리 형식으로 전달 해주어야 한다.
all이나 filter로 조회해 나오는
QuerySet은 장고에서 지원하는 객체이며
다수의 데이터를 가져오는 것이라 한다
( 나도 손에는 익었지만 제대로된 설명을 할 정도의 실력은 되지 못한다 쩝..)
Product.objects.all()
In [117]: Product.objects.all()
Out[117]: <QuerySet [<Product: Product object (1)>, <Product: Product object (2)>, <Product: Product object (3)>, <Product: Product object (4)>, <Product: Product object (5)>, <Product: Product object (6)>, <Product: Product object (7)>, <Product: Product object (8)>, <Product: Product object (9)>, <Product: Product object (10)>, <Product: Product object (11)>, <Product: Product object (12)>, <Product: Product object (13)>, <Product: Product object (14)>, <Product: Product object (15)>, <Product: Product object (16)>, <Product: Product object (17)>, <Product: Product object (18)>, <Product: Product object (19)>, <Product: Product object (20)>, '...(remaining elements truncated)...']>
정참조란 밑에 product 테이블 기준으로 보이는? 참조하고 있는 ? 컬럼을 말한다
즉 product는 city의 정로를 알 수 있다 .
class Product(models.Model):
city = models.ForeignKey('City', on_delete=models.SET_NULL, null=True)
정참조 조회는 뒤에 "." 을 넣어주면 된다 .
In [118]: Product.objects.get(id=1).name
Out[118]: '파라다이스 호텔 부산'
In [119]: Product.objects.get(id=1).city.name
Out[119]: '부산'
역참조 조회
역참조 조회는
product 테이블은 city를 가지고 있지만 반대로 city에서는 product 컬럼을 알지 못한다.
그래서 '_set' 이라는 것을 사용 해야 한다.
class City(models.Model):
name = models.CharField(max_length=45, null=True)
city 입장에서는 product을 조회하려면 뒤에_set을 넣어줘야 한다.
In [123]: city.product_set.name
<아무것도 안나옴>
In [125]: city.product_set.get(id=1).name
Out[125]: '파라다이스 호텔 부산'
아까처럼 get을 이용하여 테이블의 하나의 컬럼만 출력하기는 어렵지 않지만 다수의 컬럼을 출력하기에는
많이 복잡하다 아니 내가 못해서 그렇다.
일단 정참조로 해보자 이때 쿼리셋인 all,filter를 사용해야 하며 우리는 쿼리셋을 리스트로 벗기는 작업을 같이 해야한다
목적지의 정보를 출력하기 위해 카테고리에서 시작해보자
In [128]: Category.objects.get(id=1).destination.all()
Out[128]: <QuerySet [<Destination: Destination object (1)>, <Destination: Destination object (2)>, <Destination: Destination object (3)>]>
for문 가지고 놀기
all, values,filter
all()
In [139]: for destination in Category.objects.get(id=1).destination.all() :
...: destination
...:
In [140]: destination
Out[140]: <Destination: Destination object (3)>
In [145]: destination.name
Out[145]: '서울'
values
In [146]: for destination in Category.objects.get(id=1).destination.values() :
...: destination
...:
In [147]: destination
Out[147]:
{'id': 3,
'name': '서울',
'image_url': '"https://d2mgzmtdeipcjp.cloudfront.net/files/main/2016/10/14768018488168.png"'}
In [148]: type(destination)
Out[148]: dict
filter
for destination in Category.objects.get(id=1).destination.filter(name='서울') :
...: destination
...:
In [150]:
In [150]: destination
Out[150]: <Destination: Destination object (3)>
list()를 사용하여 쿼리셋 벗기기
In [152]: list(Category.objects.all())
...:
Out[152]:
[<Category: Category object (1)>,
<Category: Category object (2)>,
<Category: Category object (3)>]
리스트 컴프리헨션을 이용( 내가 자주 사용하는것)
In [154]: [ destination.name for destination in Category.objects.get(id=1).destination.all()]
...:
...:
...:
Out[154]: ['부산 ', '강원도', '서울']
출력 해야 할 리스트가 많을 때, 하나의 컬럼을 출력하는 리스트 컴프리헨션보다 훨씬 가독성이 좋다.
In [159]: destination_list = [
...: {
...: 'name' : destination.name,
...: 'image' : destination.image_url,
...: } for destination in Category.objects.all()]
...:
In [160]: destination_list
Out[160]:
[{'name': '투어&티켓',
'image': '"https://d2mgzmtdeipcjp.cloudfront.net/files/upload/15785505026708.png"'},
{'name': '숙소',
'image': '"https://d2mgzmtdeipcjp.cloudfront.net/files/upload/15930630727169.png"'},
{'name': '레스토랑',
'image': '"https://d2mgzmtdeipcjp.cloudfront.net/files/categories/15785570317076.png"'}]
In [161]: type(destination_list)
Out[161]: list
이제 역참조를 가져와보자.
category테이블에서 역참조를 이용하여 product 컬럼을 조회해보자
In [164]: Category.objects.get(id=2).product_set.all().name
AttributeError Traceback (most recent call last)
in
----> 1 Category.objects.get(id=2).product_set.all().name
AttributeError: 'QuerySet' object has no attribute 'name'
In [171]: Category.objects.get(id=2).product_set.all()[0].name
Out[171]: '파라다이스 호텔 부산'
막상 해보니 간단한거 같기도..?
In [178]: [category.name for category in Category.objects.get(id=2).product_set.all()]
Out[178]:
['파라다이스 호텔 부산',
'시그니엘 부산',
'신라스테이 해운대',
'라마다 앙코르 해운대',
'힐튼 부산',
'호텔 아마레 부산',
'넘버25 호텔',
'구포역 아몬드 호텔',
'호텔 아몬드 부산역',
'인 호텔',
'일로이리조트',
'GB 골든베이',
'부산 넛지567펜션',
'부산 비치하임 펜션',
'부산 해오름펜션',
'동백섬 게스트하우스',
'놀\xa0게스트하우스',
'이코노미 게스트하우스',
'휴 플러스 게스트하우스',
'캘리 호스텔',
'TGI 프라이데이 (TGIF) - 부산동래점',
'부산 파라다이스호텔 온더플레이트 뷔페',
'부산 파라다이스호텔 닉스그릴 - 브런치',
'부산 수영구 오후의 홍차 - 온라인 독점',
'롯데호텔부산 무궁화 레스토랑',
'부산 켄트호텔 by 켄싱턴 스카이라운지 브런치',
'스페인클럽 해운대점',
'온더보더 부산 서면점',
'롯데호텔 부산 더 라운지 애프터눈 티 이용권',
'롯데호텔 부산 더 라운지 뷔페']
In [179]: type([category.name for category in Category.objects.get(id=2).product_set.all()])
Out[179]: list
_set.first().(컬럼명)
in [197]: best_product_list=[{
...: 'name' : destination.category_set.first().name,
...: 'image' : destination.category_set.first().image_url,
...: }for destination in Destination.objects.all()]
In [198]: best_product_list
Out[198]:
[{'name': '투어&티켓',
'image': '"https://d2mgzmtdeipcjp.cloudfront.net/files/upload/15785505026708.png"'},
{'name': '투어&티켓',
'image': '"https://d2mgzmtdeipcjp.cloudfront.net/files/upload/15785505026708.png"'},
{'name': '투어&티켓',
'image': '"https://d2mgzmtdeipcjp.cloudfront.net/files/upload/15785505026708.png"'}]In [199]: type(best_product_list)
Out[199]: list