예제 Models.py
from multiprocessing.spawn import old_main_modules
from django.db import models
# Create your models here.
class Actors(models.Model):
first_name = models.CharField(max_length=45)
last_name = models.CharField(max_length=45)
date_of_birth = models.DateField()
class Meta:
db_table = 'actors'
class Movies(models.Model):
title = models.CharField(max_length=45)
relase_data = models.DateField()
running_time = models.IntegerField()
class Meta:
db_table = 'movies'
class actors_movies(models.Model):
actor = models.ForeignKey('Actors', on_delete=models.CASCADE)
movie = models.ForeignKey('Movies', on_delete=models.CASCADE)
class Meta:
db_table = 'actors_movies'
class Test_acces(models.Model):
name=models.CharField(max_length=45)
test=models.OneToOneField('Test', on_delete=models.CASCADE)
class Test(models.Model):
name=models.CharField(max_length=45)
해당객체가 다른 객체의 Foreign Key 를 가지고 있거나 1:1 관계인 상황에서 참조하는경우
In [12]: a = Test.objects.get(id=2)
In [13]: b = a.test_acces.name
In [14]: b
Out[14]: 'hello_2'
select_related()없이 바로 relation중인 객체 정보를 볼 수 있다.
그럼어떤 상황에 왜 select_related()
를 사용하는 걸까?
Hit(Database에 query를 요청하는 횟수)를 최소화하여 성능을 높인다.
한번의 Hit로 관계데이터를 가져오는 것과 같다.
In [16]: a = Test.objects.**select_related**('test_acces').get(id=3)
In [17]: a
Out[17]: <Test: Test object (3)>
In [18]: a.test_acces.name
Out[18]: 'hello_3'
나를 참조하는 Table접근
다른 객체가 ForeignKey를 가지고 있거나 N:N 관계인 상황
해당객체를 참조하고 있는 다른 객체를 참조 하려는 경우
Testacces 에서 test에 저장된 name 을 보고 싶은경우
In [20]: a = Testacces.objects.get(id=3)
In [21]: a.tested.name
Out[21]: 'test_3'
역참조 사용 방법
1) 테이블명소문자_set
In [84]: c = Actors.objects.get(id=4)
In [85]: c.actors_movies_set.all()[0].movie.title
Out[85]: 'hello_3'
In [86]: d = Movies.objects.get(id=3)
In [88]: d.actors_movies_set.all()[0].actor.first_name
Out[88]: '3'
_set을안쓸경우
In [87]: d.actors_movies.all()[0].actor.first_name
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Input In [87], in <cell line: 1>()
----> 1 d.actors_movies.all()[0].actor.first_name
AttributeError: 'Movies' object has no attribute 'actors_movies'
에러가 발생
2) related_name 지정 & 접근
# 테이블에 related_name이 지정되었을 경우
만 사용가능
<QuerySet [num]>
을 리턴하기 때문에 인덱싱을 먼저 한뒤 객체 내용을 검색 할 수 있다.<QuerySet Object>
를 리턴한다.