django model에서 ForeignKey로 지정된 객체를 호출하는 경우
외래키 객체에 대한 참조가 발생하였다고 한다
물론 실제 DB에는 참조하는 객체의 pk가 저장되지만 이를 불러올 때
django는 이를 객체화하여 접근할 수 있게 한다
위의 django model에 대해서
Beverage.objects.first().category # 이 구문을 실행하면
SELECT "beverages"."id", "beverages"."category_id",
"beverages"."name_kor", "beverages"."name_eng",
"beverages"."description_top", "beverages"."description_bottom",
"beverages"."thumb_nail" FROM "beverages"
ORDER BY "beverages"."id"
SELECT "menus"."id", "menus"."name" FROM "menus" WHERE "menus"."id"
위의 SQL QUERY가 발생한다
이때 이 쿼리는 category라는 ForeignKey를 정방향으로 참조한다
ForeinKey에 의해 참조되고있는 모델에서 참조하는 모델을
호출하는 경우를 역참조 라고 한다
일반적으로 역참조에는 여러가지 방식이 있다
cat1= Category.objects.first()
Beverage.objects.filter(category=cat1)
SELECT "menus"."id", "menus"."name"
FROM "menus" ORDER BY "menus"."id"
SELECT "beverages"."id", "beverages"."category_id",
"beverages"."name_kor", "beverages"."name_eng",
"beverages"."description_top", "beverages"."description_bottom",
"beverages"."thumb_nail" FROM "beverages"
WHERE "beverages"."category_id"
tall = Size.objects.first()
tall.nutrientbysize_set.all()
SELECT "sizes"."id", "sizes"."name", "sizes"."size_ml",
"sizes"."size_oz" FROM "sizes" ORDER BY "sizes"."id"
SELECT "nutrient_by_sizes"."id", "nutrient_by_sizes"."beverage_id_id",
"nutrient_by_sizes"."size_id_id", "nutrient_by_sizes"."kcal",
"nutrient_by_sizes"."saturated_fat", "nutrient_by_sizes"."protein",
"nutrient_by_sizes"."sodium", "nutrient_by_sizes"."saccharide",
"nutrient_by_sizes"."caffeine" FROM "nutrient_by_sizes"
WHERE "nutrient_by_sizes"."size_id_id"
related_name 사용
위 Beverage모델에서 처럼 related_name을 ForeignKey선언 시 속성값을
인자로 넘겨주었을 경우에만 사용 가능하다
cat1 = Category.objects.first()
cat1.beverages.all()
SELECT "menus"."id", "menus"."name" FROM "menus"
ORDER BY "menus"."id"
SELECT "beverages"."id", "beverages"."category_id",
"beverages"."name_kor", "beverages"."name_eng",
"beverages"."description_top", "beverages"."description_bottom",
"beverages"."thumb_nail" FROM "beverages"
WHERE "beverages"."category_id" = 1
related_name이 설정되었을 경우 related_name을 통해 마치 Category가
Beverage를 참조하고 있는것 처럼 사용할 수 있다
추가로 위 두 방식에 비하여 DB 접근 속도 또한 괄목할 정도로 빠르다