장고 프로젝트를 진행하면서 점점 모델을 구체적으로 정의하고, 추가되는 기능이 많아지면서 모델과 모델 사이의 데이터베이스 구조가 복잡해진다.
모델 데이터를 뷰 함수나 템플릿에서 사용하려할 때, 그것을 어떻게 가져와야하는지가 너무 햇갈렸다. 그리고 함수가 받는 인자가 어떤 것은user_id
라고 하고 어떤 것은 user.id
라고 하는데 이것도 너무 햇갈렸다..
사용자(User)의 식별자(ID)이다.
특정 사용자의 정보를 검색하거나, 사용자와 관련된 작업을 수행하는 함수에서 이 인자를 사용할 수 있다.
함수에 사용자 id를 전달하는데 사용된다.
예를들어, User.objects.get(id=user_id)
의 user_id
는 사실 urls.py
에 우리가 정한 url패턴
에 들어가는 user_id
가 서버에서 user데이터를 사용하기 위한 목적에 있으며, 우리는 받은 user_id
값을 그 url에 연결된 view함수에서 데이터베이스의 user 데이터의 id필드 값이 사용자가 요청한 값과 같은 인스턴스를 가져오는데 사용한다.
User 모델의 인스턴스(어떤 사용자의 데이터)
에서 그 사용자의 id를 가져오는 방법이다.
이미 존재하는 사용자의 객체(인스턴스) 데이터의 id를 얻기 위해 사용된다.
예를들어, Post.objects.get(user=request.user.id)
는 Post 모델의 post 데이터의 user_id필드 값이 User 모델의 user데이터에 저장되어 있는 사용자의 id값과 같은 인스턴스를 가져오는 경우이다.
모델 간의 관계를 활용해서 정보를 찾는 방법
아래와 같은 모델이 정의되어 있다고 가정해보자.
from django.db import models
class Person(models.Model)
name = models.CharField(max_length=100)
class Car(models.Model)
owner = models.ForeignKey(Person, related_name = 'my_cars', on_delete=models.CASCADE)
type = models.CharField(max_length=100)
color = models.CharField(max_length=100)
Person 모델과 Car 모델은 1:N 관계
이다.
그리고 Car 모델은 Person 모델을 참조하고 있다.
Car 모델에는 name이라는 속성(필드)
가 없지만 아래와 같이 User의 name(이름)을 가져올 수 있다.
that_car = Car.object.get(id=1)
that_car.owner.name
이 데이터를 탬플릿에서 쓴다고 한다면,
[view.py]
def test(request):
if request.method == 'GET':
...
parked_car = that_car.owner.name
...
return render(request, 'test.html', {'tem_parked_car' : parked_car})
[test.html]
<html>
...
<body>
...
<h1> {{ tem_parked_car.name }} <h1>
...
<body>
<html>
이 경우를 정참조
라고 한다.
정방향으로, '차 모델'에 없는 '소유주의 이름'을 'Owner 모델'을 참조하고 있는 'Car 모델'의 'owner foreignkey 속성'
을 타고 들어가서 Owner 인스턴스
의 name값
을 가져오는 것이다.
역참조는 정참조와 반대로, ForeignKey 속성이 없는 객체에서 관계된 모델을 참조하는 경우이다.
위에 정의된 모델들을 참고하자면,
Person 모델
에는 Car에 대한 정보가 아얘 없다.
하지만 Person 모델 인스턴스 데이터
에서 Car 데이터
를 가져올 수 있는데, 이 방법이 역참조
이다.
만약, Person 모델 인스턴스
로부터 해당 사람이 가진 차의 데이터를 가져오고 싶다고 해보자.
이 때, 쓰이는 것이 related_name 이다.
my_favorite_car = me.my_cars.get(type='포르쉐')
my_first_car = me.my_cars.get(id=1)
my_cars_all = me.my_cars.all()
my_red_cars = me.my_cars.filter(color='red')
me
는 Person 모델
의 인스턴스이다.
해당 인스턴스와 연결된 소유 차량 중 특정 조건의 Car 모델
의 인스턴스 데이터를 가져올 수 있다.
템플릿에서 반복문을 통해 나의 차량을 모두 나열할 수 있다.
{% for car in my_cars_all %}
<p> {{ car }} <p>
{% endfor %}
🐥 정참조는 필드를 통해 객체에 직접 접근하고, 역참조는 ForeignKey 또는 related_name을 통해 관련된 객체를 역으로 참조하는 것
🥚🐣🐤🐥🐓🐔