πŸͺ£ Many to Many 관계 ν…Œμ΄λΈ”

νŒ”λ¦¬λ™Β·2021λ…„ 8μ›” 17일
1
post-thumbnail

μž₯κ³  Many to Many κ΄€κ³„ν…Œμ΄λΈ”μ— λŒ€ν•΄μ„œ μ•Œμ•„λ³΄μž.

πŸš€ Many To Many

  • μž₯κ³ μ—μ„œλŠ” Mant To many μ˜΅μ…˜μ„ 지정할 수 μžˆλŠ”λ° λ‹¨μˆœνžˆ 관계 ν…Œμ΄λΈ”μ„ λ‘λŠ” 것과 Many To Manyμ˜΅μ…˜μ„ μ§€μ •ν–ˆμ„ λ•Œ 차이에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

  • μ˜ˆμ‹œ λ°μ΄ν„°λŠ” μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

    μ˜ν™”μ •λ³΄λ₯Ό κ°–κ³  μžˆλŠ” μ˜ν™” ν…Œμ΄λΈ”κ³Ό 배우 정보λ₯Ό λ‹΄κ³  μžˆλŠ” λ°°μš°ν…Œμ΄λΈ” 그리고 이 λ‘˜μ„ μ΄μ–΄μ£ΌλŠ”μ€‘κ³„ν…Œμ΄λΈ” μž…λ‹ˆλ‹€.

🀝 쀑계 ν…Œμ΄λΈ” 생성

  • Many to Many ν•„λ“œλ₯Ό μ§€μ •ν•˜μ§€ μ•Šκ³  쀑계 ν…Œμ΄λΈ”λ§Œ λ§Œλ“€μ–΄λ³΄κ² μŠ΅λ‹ˆλ‹€.
class Actor(models.Model):
    name = models.CharField(max_length=45)
    
class Movie(models.Model):
    title = models.CharField(max_length=256)
                              

class ActorMovie(models.Model):
    actor = models.ForeignKey(Actor, on_delete=models.CASCADE)
    movie = models.ForeignKey(Movie, on_delete=models.CASCADE)

가독성을 μœ„ν•΄μ„œ 컬럼의 μˆ˜λŠ” μ΅œλŒ€ν•œ μ€„μ˜€μŠ΅λ‹ˆλ‹€.

데이터λ₯Ό λ„£μ–΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

  • μ˜ν™” 생성
m1 = Movie.objects.create(title="ν…Œλ„·")
m2 = Movie.objects.create(title="λΈ”λ ˆμ΄λ“œλŸ¬λ„ˆ2049")
  • 배우 생성
a1 = Actor.objects.create(name="μ‘΄ λ°μ΄λΉ„λ“œ μ›Œμ‹±ν„΄")
a2 = Actor.objects.create(name="라이언 고슬링")
  • 관계 ν…Œμ΄λΈ” 데이터 λ„£κΈ°
ActorMovie.objects.create(actor=a1, movie=m1)
ActorMovie.objects.create(actor=a2, movie=m2)
  • 1번 배우 μ‘΄ λ°μ΄λΉ„λ“œ μ›Œμ‹±ν„΄μ˜ μΆœμ—° μ˜ν™”λ₯Ό μ‘°νšŒν•΄ λ³΄κ² μŠ΅λ‹ˆλ‹€.
a1.actormovie_set.all()

for actormovie in a1.actormovie_set.all():
    print(actormovie.movie.title)

μ˜ν™”, 배우 관계 ν…Œμ΄λΈ”μ„ μ—­μ°Έμ‘°ν•΄μ„œ 객체λ₯Ό μƒμ„±ν•΄μ„œ μš”μ†Œλ₯Ό ν•˜λ‚˜ λΉΌμ„œ .movie.title둜 μ ‘κ·Όν•΄μ•Ό ν•©λ‹ˆλ‹€. μ’€ λ²ˆκ±°λ‘­λ‹€λŠ” λŠλ‚Œμ΄ λ“­λ‹ˆλ‹€.

πŸͺ£ Many to Many μ„€μ •

  • μ΄λ²ˆμ—λŠ” μ˜ν™” ν…Œμ΄λΈ”μ— actorμΉΌλŸΌμ„ λ„£κ³  many to manyλ₯Ό μ§€μ •ν•˜κ² μŠ΅λ‹ˆλ‹€.
class Actor(models.Model):
    name = models.CharField(max_length=45)
    
class Movie(models.Model):
    title = models.CharField(max_length=256)
    actor = models.ManyToManyField(Actor,
                                   through='ActorMovie',
                                   related_name='movies')
                            
class ActorMovie(models.Model):
    actor = models.ForeignKey(Actor, on_delete=models.CASCADE)
    movie = models.ForeignKey(Movie, on_delete=models.CASCADE)
  • through μ˜΅μ…˜μ€ κ΄€κ³„ν…Œμ΄λΈ”μ„ μ§€μ •ν•˜λŠ” μ˜΅μ…˜
  • related_name은 μ—­μ°Έμ‘°λ₯Ό ν•˜κΈ°μœ„ν•œ 이름 μ„€μ •

이제 μ˜ν™” λ‹€μ‹œ μ‘΄ λ°μ΄λΉ„λ“œ μ›Œμ‹±ν„΄λ°°μš°μ˜ μ˜ν™”λ₯Ό μ‘°νšŒν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

a1.movies.all()
for movie in a1.movies.all():
	print(movie.title)
>>> "ν…Œλ„·"

관계 ν…Œμ΄λΈ”μ„ μƒμ„±ν•œ κ²½μš°λ³΄λ‹€ λ©”μ†Œλ“œ ν•œκ°œλ₯Ό 덜 μ“Έ 수 μžˆμŠ΅λ‹ˆλ‹€. .movie.title -> .title

μ’€ 더 μ§κ΄€μ μ΄κ²Œ κ΄€κ³„ν•œ ν…Œμ΄λΈ”μ„ μ‘°νšŒν•  수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ§ͺ 쀑계 ν…Œμ΄λΈ” μ—†μ• κΈ°

  • 쀑계 ν…Œμ΄λΈ”μ„ μ—†μ• κ³  Many to Manyμ˜΅μ…˜μ„ 지정해도 λ©λ‹ˆλ‹€.
class Actor(models.Model):
    name = models.CharField(max_length=45)
    
class Movie(models.Model):
    title = models.CharField(max_length=256)
    actor = models.ManyToManyField(Actor,
                                   related_name='movies')

μ΄λ ‡κ²Œ ν•˜λ©΄ μ•„κΉŒμ™€ 같이 데이터λ₯Ό μ‘°νšŒν•  수 μžˆμŠ΅λ‹ˆλ‹€.

a1 = Actor.objects.create(name="μ‘΄ λ°μ΄λΉ„λ“œ μ›Œμ‹±ν„΄")
a1.movies.all()
for movie in a1.movies.all():
	print(movie.title)
>>> "ν…Œλ„·"

πŸ€” 쀑계 ν…Œμ΄λΈ”μ€ μ™œλ‘˜κΉŒ?

  • κ·Έλ ‡λ‹€λ©΄ 의문이 ν•˜λ‚˜ μƒκΉλ‹ˆλ‹€. λ­ν•˜λŸ¬ μ€‘κ³„ν…Œμ΄λΈ”μ„ λ‘λŠ”κ°€?

쀑계 ν…Œμ΄λΈ”μ— κ΄€κ³„ν•˜λŠ” ν…Œμ΄λΈ” foreignkey외에 λ‹€λ₯Έν•­λͺ©μ„ μΆ”κ°€ν•˜κ³ μž ν•  λ•Œ ν•„μš”ν•©λ‹ˆλ‹€.

μ€‘κ³„ν…Œμ΄λΈ”μ„ μ•ˆ λ§Œλ“€κ³  Many to Manyμ˜΅μ…˜μ„ μ§€μ •ν•˜λ©΄ λ°μ΄ν„°λ² μ΄μŠ€μ— μžλ™μœΌλ‘œ κ΄€κ³„ν…Œμ΄λΈ”μ΄ μƒμ„±λ˜λŠ”λ° 이 ν…Œμ΄λΈ”μ— μ»¬λŸΌμ„ μΆ”κ°€ν•˜κ³ μž ν•˜λ©΄ 직접 μž₯κ³ μ—μ„œ λ§Œλ“€μ–΄μ•Ό μΆ”κ°€ν•˜κ³ μž ν•˜λŠ” 컬럼이 λ°˜μ˜λ©λ‹ˆλ‹€.

profile
λ°°μ›€μ˜ 기둝

0개의 λŒ“κΈ€