
λ°μ΄ν°λ² μ΄μ€μ Many-to-Many relationship(λ€λλ€ κ΄κ³)λ ν ν μ΄λΈμ μ¬λ¬ λ μ½λκ° λ€λ₯Έ ν μ΄λΈμ μ¬λ¬ λ μ½λμ μ°κ²°λμ΄ μλ κ΄κ³λ₯Ό λ§νλ€.
class Movie(models.Model):
title = models.CharField(max_length=45)
release_date = models.DateField()
running_time = models.IntegerField()
class Meta:
db_table = 'movies'
class Actor(models.Model):
first_name = models.CharField(max_length=45)
last_name = models.CharField(max_length=45)
date_of_birth = models.DateField()
movies = models.ManyToManyField(Movie, related_name="actors_movies")
class Meta:
db_table = 'actors'
μ₯κ³ κ³΅μλ¬Έμμμλ ManyToManyFieldλ₯Ό μ μνλ©΄, μλμΌλ‘ λ ν μ΄λΈ μ¬μ΄μ κ΄κ³λ₯Ό κ΄λ¦¬ν΄μ£Όλ μ€κ° ν μ΄λΈμ μμ±νλ€κ³ λμ΄ μλ€. μ΄ ν μ΄λΈμ μ°λ¦¬κ° μμ±ν λͺ¨λΈμλ μμ§λ§, λ°μ΄ν°λ² μ΄μ€λ₯Ό νμΈνλ©΄ λ€λλ€κ΄κ³μ λ ν μ΄λΈ μ΄λ¦μ _λ‘ μ΄μ΄μ€ λ³λμ ν μ΄λΈμ΄ μμ±λ κ²μ λ³Ό μ μλ€.
μ΄ μ€κ° ν μ΄λΈμ λ ν μ΄λΈμ idλ₯Ό κ°κ° νλλ‘ κ°μ§κ³ μλ€. κ·Έλ κΈ° λλ¬Έμ κ° ν μ΄λΈμ λ°μ΄ν°κ° μ‘΄μ¬νμ§ μμΌλ©΄ μ€κ° ν μ΄λΈμλ primary keyκ° μ‘΄μ¬νμ§ μλλ€.
μμμ μμ±ν μμλ₯Ό 보면, λ°°μ° ν μ΄λΈμ μν ν μ΄λΈμ μ°Έμ‘°νλ νλκ° μ‘΄μ¬νλ€. κ·Έλ κΈ° λλ¬Έμ μν ν μ΄λΈμμ λ°°μ° ν μ΄λΈμ λ°μ΄ν°λ₯Ό μ§μ μ μΌλ‘ κ°μ Έμ¬ μ μλ€.
movies = models.ManyToManyField(Movie, related_name="actors_movies")
related_nameμ 'μ°Έμ‘°λλ ν μ΄λΈμ΄ μ°Έμ‘°νλ ν μ΄λΈμ λ°μ΄ν°λ₯Ό κ°μ Έμ€κ³ μΆμ λ μ¬μ©νλ μ΄λ¦'μ μ μνλ κ²μ΄λ€. μ΄ κ²½μ° μνκ° λ°°μ°μ λ°μ΄ν°λ₯Ό κ°μ Έμ€κ³ μΆμ λ actors_moviesλ₯Ό μΈ μ μλ€.
>>> movie = Movie.objects.get(id=1)
>>> movie.actors_movies.all()
<QuerySet [<Actor: Actor object (1)>]>
>>> movie.actors_movies.first()
<Actor: Actor object (1)>
λ°μ΄ν° κ°μ κ΄κ³μ±μ κ°μ§κ² νκΈ° μν΄ λ°°μ° ν μ΄λΈμμ μνλ₯Ό μΆκ°ν μλ μμ§λ§, λ°λλ‘ μν ν μ΄λΈμμ μνλ₯Ό μ°μ λ°°μ° λ°μ΄ν°λ₯Ό μΆκ°ν μλ μλ€.
>>> actor = Actor.objects.get(id=4)
>>> movie = Movie.objects.get(id=10)
>>> actor.movies.add(movie)
>>> actor = Actor.objects.get(id=5)
>>> movie = Movie.objects.get(id=9)
>>> movie.actors_movies.add(actor)
λ°μ΄ν°λ₯Ό 쿼리ν λλ ν ν μ΄λΈμμ μλ ν μ΄λΈμ μλ λ°μ΄ν°λ₯Ό μ°κ΄μμΌ μ‘°νν μ μλ€. λ€μκ³Ό κ°μ΄ λ°°μ° ν μ΄λΈμμ νν°λ‘ μν ν μ΄λΈμ λ°μ΄ν° μ€ 'T'λ‘ μμνλ μν νμ΄νμ κ°μ§ λ°°μ°λ€μ μΆμΆν μλ μλ€.
>>> Actor.objects.filter(movies__title__startswith="T")
<QuerySet [<Actor: Actor object (1)>, <Actor: Actor object (1)>, <Actor: Actor object (2)>, <Actor: Actor object (2)>, <Actor: Actor object (3)>, <Actor: Actor object (4)>, <Actor: Actor object (5)>]>
λ§μ°¬κ°μ§λ‘ μν ν μ΄λΈμμ νν°λ‘ λ°°μ° ν μ΄λΈμ λ°μ΄ν° μ€ μ΄λ¦μ 'a'κ° λ€μ΄κ°λ λ°°μ°λ₯Ό κ°μ§ μνλ€μ μΆμΆν μ μλ€.
>>> Movie.objects.filter(actors_movies__first_name__contains="a")
<QuerySet [<Movie: Movie object (1)>, <Movie: Movie object (2)>, <Movie: Movie object (3)>, <Movie: Movie object (6)>, <Movie: Movie object (7)>, <Movie: Movie object (8)>, <Movie: Movie object (9)>, <Movie: Movie object (10)>, <Movie: Movie object (9)>]>
μ₯κ³ μμλ ManyToManyFieldλ‘ λ°μ΄ν°λ₯Ό μ μνλ©΄ μλμΌλ‘ λ ν μ΄λΈμ κ΄κ³λ₯Ό κ΄λ¦¬ν΄μ£Όλ ν μ΄λΈμ μμ±νλλ°, μ΄κ²μ through modelμ΄λΌκ³ νλ€. κ°λ°μκ° μ§μ through modelμ μ μνλ©΄ νλλ₯Ό μΆκ°ν μ€κ° ν μ΄λΈμ μμ±ν μ μλ€.
μλ μμ±λλ ν μ΄λΈμλ ν μ΄λΈμ κ³ μ idμ λ ν μ΄λΈμ idλ§ μ‘΄μ¬νμ§λ§, κ°λ°μκ° μ§μ μ μνλ©΄ λμ± μμΈν λ°μ΄ν°λ₯Ό ꡬμΆν μ μλ€.
λ€λ§ through modelμ μ μν λλ λͺ¨λΈμ μ²μ μμ±ν λλΆν° through modelμ μ μν΄ μ£Όκ±°λ λ°μ΄ν°λ² μ΄μ€λ₯Ό μ λΆ dropνκ³ λ€μ μμν΄μΌ νλ€.
ν κ°μ§ μ£Όμν μ μ through modelμ μμ±νλ€λ©΄ λ°μ΄ν°λ₯Ό μΆκ°ν λλ μ€κ° ν μ΄λΈμ μ§μ μ μΌλ‘ λ°μ΄ν°λ₯Ό λ£μ΄ μ£Όμ΄μΌ νλ€λ μ μ΄λ€. μλ μμ±λμμ λμ²λΌ μΆκ°νλ©΄ μλ¬κ° λ°μνλ€.