파파비의 블로그

[python/파이썬] Cross Model Queries 본문

개발/django

[python/파이썬] Cross Model Queries

N. Dave 2021. 6. 19. 11:05
반응형

1) Book -> Author로 query하기

Book.objects.filter(author__fieldname = "data")

 

>> 필터에 먼저 book에서의 원하는 필드 이름을 적고, 그 필드가 만약 또 다른 relation하고 연결되어 있다면

__를 적으면 해당 relation의 필드로 접근이 가능하다.

 

>> Book.objects.filter(author__last_name = "Rowling")

: author 필드는 author class의 객체가 들어가므로 __를 통해 author class의 last_name 속성에 접근하였다.

 

>> Book.objects.filter(author__last_name__contains = "wling")

: 최종 필드에 도착한 이후에는 __를 적고 위처럼 modifers 들을 사용할 수 있다.

 

 

2) Author -> Book로 query하기

Author 객체에는 Book 객체로 연결되는 필드가 없는데 어떻게 Author 객체에서 연결된 Book 객체로 갈 수 있을까?

django가 알아서 만들어주어서 우리는 딱히 세팅할 필요는 없다.

 

셸을 통해 아까 확인해보자

jk.book_set
<django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager object at 0x000001CE1DA79CD0>
jk.book_set.all()
<QuerySet [<Book: Harry Potter 1 5)>]>
>>> jk.book_set.get(title="Harry Potter 1") 
<Book: Harry Potter 1 5)>

book_set 이라는 필드가 author 객체에 자동으로 생성되어 있다.

book_set . all(), get(), filter() 등 쿼리하던 방식대로 편하게 하면 된다.

 

그런데, 왜 속성 이름이 book_set일까?

1) 우리가 따로 설정을 해주지 않았기 때문에 자동으로 설정된 것

>> book은 연결된 class Book을 전부 소문자 한 후, _set이 포함되는 형식으로 자동 default이다.

 

2) 설정은 Book class에서 author 필드를 설정할 때, 해주면 book_set 말고 다른 필드명을 사용할 수 있다.

class Book(models.Model):
    title = models.CharField(max_length=50)
    rating = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)])
    author = models.ForeignKey(Author, on_delete=models.CASCADE, null=True)
    is_bestselling = models.BooleanField(default=False)
    slug = models.SlugField(default="", null=False, db_index=True)
    
    
    # author = models.ForeignKey(Author, on_delete=models.CASCADE, null=True)
    # >> author = models.ForeignKey(Author, on_delete=models.CASCADE, null=True, related_name = "books")

ForeignKey에 related_name 부분을 통해 설정할 수 있다.

books라고 설정되면 나중에 author객체.books 라고만 치면 연결된 모든 book 객체에 접근할 수 있다.

 

반응형
Comments