2023/09/14 [TIL] 정참조 & 역참조

장현웅·2023년 9월 15일
0

🥚 다른 모델의 데이터베이스 필드값을 어떻게 가져오는거지?


장고 프로젝트를 진행하면서 점점 모델을 구체적으로 정의하고, 추가되는 기능이 많아지면서 모델과 모델 사이의 데이터베이스 구조가 복잡해진다.

모델 데이터를 뷰 함수나 템플릿에서 사용하려할 때, 그것을 어떻게 가져와야하는지가 너무 햇갈렸다. 그리고 함수가 받는 인자가 어떤 것은user_id라고 하고 어떤 것은 user.id라고 하는데 이것도 너무 햇갈렸다..

🐣 인자값 user_id & 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'를 가져오는 경우

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')

mePerson 모델의 인스턴스이다.

해당 인스턴스와 연결된 소유 차량 중 특정 조건의 Car 모델의 인스턴스 데이터를 가져올 수 있다.

템플릿에서 반복문을 통해 나의 차량을 모두 나열할 수 있다.

{% for car in my_cars_all %}

<p> {{ car }} <p>
    
{% endfor %}

🥚🐣🐤🐥🐓🐔

0개의 댓글