OneToOne 관계일때는 annoying의 AutoOneToOne을 사용하자.
https://uiandwe.tistory.com/1225
View에서의 쿼리 사용 방법
Django의 쿼리는 마지막까지 지연(lazy)된다
Django의 쿼리셋(queryset)은 데이터베이스의 여러 레코드(row)를 나타냅니다.
person_queryset = Person.objects.filter(first_name="uiandwe")
이 코드는 DB에 어떤 쿼리도 전달하지 않습니다. 여러분이 person_queryset에 필터를 추가하거나 person_queryset을 함수에 전달한다 해도, 이는 DB에 아무런 메시지도 전달하지 않습니다. 왜냐하면 DB에 쿼리를 전달하는 일은 웹 애플리케이션을 느려지게 하는 주범 중 하나이기 때문입니다. 즉 최대한 마지막 실행 직전에 쿼리를 실행하여 데이터를 가져옵니다.
DB의 레코드를 진짜로 가져오려면(fetch) 다음과 같이 쿼리셋을 순회(iterate)해야 합니다.
for person in person_set:
print(person.last_name)
Django의 쿼리셋은 캐시된다
쿼리셋을 순회하는 시점에, 쿼리셋에 해당하는 DB의 레코드들을 실제로 가져오며(fetch), 이는 모두 Django 모델로 변환됩니다. 이를 가리켜 평가(evaluation)라고 합니다. 평가된 모델들은 쿼리셋의 내장 캐시에 저장되며, 덕분에 여러분이 쿼리셋을 다시 순회하더라도 똑같은 쿼리를 DB에 다시 전달하지는 않는습니다.
pet_set = Pet.objects.filter(species="Dog")
# 쿼리가 '평가'되고, 결과가 캐시된다.
for pet in pet_set:
print(pet.first_name)
# 똑같은 순회를 반복할 경우 이미 캐시된 쿼리셋이 사용된다.
for pet in pet_set:
print(pet.last_name)
if 문에서는 쿼리셋 평가가 발생하며 결과 전체가 필요하지 않은 경우 쿼리셋 캐시가 문제가 됩니다.
city_set = City.objects.filter(name="Cambridge")
# if 문은 쿼리셋을 평가한다
if city_set:
# 쿼리셋의 전체 결과가 필요하지는 않은 상황임에도
# ORM은 전체 결과를 가져온다(fetch)
그래서 get() + DoesNotExist/ObjectDoesNotExist or exists() 사용
try:
city_set = City.objects.get(name="Cambridge”)
except City.DoesNotExist:
pass
try:
city_set = City.objects.get(name="Cambridge”)
except ObjectDoesNotExist:
pass
city_set = City.objects.filter(name="Cambridge")
# exists()는 쿼리셋 캐시를 만들지 않으면서 레코드가 존재하는지 검사한다
if city_set():
# DB에서 가져온 레코드가 하나도 없다면
# 트래픽과 메모리를 절약할 수 있다
print("hell hell hell hell world!")
참조자료
http://raccoonyy.github.io/using-django-querysets-effectively-translate/
https://wayhome25.github.io/django/2017/07/25/tsd7-django-query-database/
'web > Django' 카테고리의 다른 글
How Django process a request (0) | 2021.05.10 |
---|---|
django RemoteUserAuthentication 는 별거 없습니다. (0) | 2020.06.24 |
django query 기초 3 (0) | 2020.03.25 |
django query 기초2 (0) | 2020.02.18 |
django query 기초1 (0) | 2020.02.16 |