Django

GreenBeanΒ·2021λ…„ 4μ›” 29일
post-thumbnail

ManyToManyField

βœ“ Many-to-Many relationship

λ°μ΄ν„°λ² μ΄μŠ€μ˜ Many-to-Many relationship(λ‹€λŒ€λ‹€ 관계)λŠ” ν•œ ν…Œμ΄λΈ”μ˜ μ—¬λŸ¬ λ ˆμ½”λ“œκ°€ λ‹€λ₯Έ ν…Œμ΄λΈ”μ˜ μ—¬λŸ¬ λ ˆμ½”λ“œμ™€ μ—°κ²°λ˜μ–΄ μžˆλŠ” 관계λ₯Ό λ§ν•œλ‹€.

βœ“ ManyToManyField

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κ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€.

βœ“ νŠΉμ§•1 : 데이터λ₯Ό κ°€μ Έμ˜¬ λ•Œ νŠΉλ³„ν•œ 방법이 ν•„μš”

μœ„μ—μ„œ μž‘μ„±ν•œ μ˜ˆμ‹œλ₯Ό 보면, 배우 ν…Œμ΄λΈ”μ— μ˜ν™” ν…Œμ΄λΈ”μ„ μ°Έμ‘°ν•˜λŠ” ν•„λ“œκ°€ μ‘΄μž¬ν•œλ‹€. κ·Έλ ‡κΈ° λ•Œλ¬Έμ— μ˜ν™” ν…Œμ΄λΈ”μ—μ„œ 배우 ν…Œμ΄λΈ”μ˜ 데이터λ₯Ό μ§μ ‘μ μœΌλ‘œ κ°€μ Έμ˜¬ 수 μ—†λ‹€.

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

βœ“ νŠΉμ§•2 : 데이터 μΆ”κ°€ & μΏΌλ¦¬λŠ” μ–‘μͺ½μ—μ„œ κ°€λŠ₯

데이터 κ°„μ˜ 관계성을 κ°€μ§€κ²Œ ν•˜κΈ° μœ„ν•΄ 배우 ν…Œμ΄λΈ”μ—μ„œ μ˜ν™”λ₯Ό μΆ”κ°€ν•  μˆ˜λ„ μžˆμ§€λ§Œ, λ°˜λŒ€λ‘œ μ˜ν™” ν…Œμ΄λΈ”μ—μ„œ μ˜ν™”λ₯Ό 찍은 배우 데이터λ₯Ό μΆ”κ°€ν•  μˆ˜λ„ μžˆλ‹€.

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

βœ“ νŠΉμ§•3 : Through Model

μž₯κ³ μ—μ„œλŠ” ManyToManyField둜 데이터λ₯Ό μ •μ˜ν•˜λ©΄ μžλ™μœΌλ‘œ 두 ν…Œμ΄λΈ”μ˜ 관계λ₯Ό κ΄€λ¦¬ν•΄μ£ΌλŠ” ν…Œμ΄λΈ”μ„ μƒμ„±ν•˜λŠ”λ°, 이것을 through model이라고 ν•œλ‹€. κ°œλ°œμžκ°€ 직접 through model을 μ •μ˜ν•˜λ©΄ ν•„λ“œλ₯Ό μΆ”κ°€ν•œ 쀑간 ν…Œμ΄λΈ”μ„ 생성할 수 μžˆλ‹€.

μžλ™ μƒμ„±λ˜λŠ” ν…Œμ΄λΈ”μ—λŠ” ν…Œμ΄λΈ”μ˜ 고유id와 두 ν…Œμ΄λΈ”μ˜ id만 μ‘΄μž¬ν•˜μ§€λ§Œ, κ°œλ°œμžκ°€ 직접 μ •μ˜ν•˜λ©΄ λ”μš± μžμ„Έν•œ 데이터λ₯Ό ꡬ좕할 수 μžˆλ‹€.

λ‹€λ§Œ through model을 μ •μ˜ν•  λ•ŒλŠ” λͺ¨λΈμ„ 처음 생성할 λ•ŒλΆ€ν„° through model을 μ •μ˜ν•΄ μ£Όκ±°λ‚˜ λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ „λΆ€ dropν•˜κ³  λ‹€μ‹œ μ‹œμž‘ν•΄μ•Ό ν•œλ‹€.

ν•œ κ°€μ§€ μ£Όμ˜ν•  점은 through model을 μƒμ„±ν–ˆλ‹€λ©΄ 데이터λ₯Ό μΆ”κ°€ν•  λ•ŒλŠ” 쀑간 ν…Œμ΄λΈ”μ— μ§μ ‘μ μœΌλ‘œ 데이터λ₯Ό λ„£μ–΄ μ£Όμ–΄μ•Ό ν•œλ‹€λŠ” 점이닀. μžλ™ μƒμ„±λ˜μ—ˆμ„ λ•Œμ²˜λŸΌ μΆ”κ°€ν•˜λ©΄ μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

profile
🌱 Backend-Dev | hwaya2828@gmail.com

0개의 λŒ“κΈ€