[Django] CRUD - 2

Jungmin Seo·2021년 6월 23일

Django

목록 보기
3/4

🥣 ManyToManyField + Foreign Key

models.py

  • Movie5Actor5의 중간테이블 작성
  • Movie5를 참조하는 클래스Actor5ManyToManyField 추가
movie = models.ManyToManyField(Movie5, through='ActorMovie5', related_name='haha')
  • through= Movie5와 Actor5의 중간테이블 클래스
  • related_name= 역참조할 때 클래스_set을 대체할 이름

class Movie5(models.Model):
    title = models.CharField(max_length=20)
    release_date = models.DateField() 
    running_time = models.IntegerField() 

    class Meta:
        db_table = 'movies5'

# Movie5를 참조하는 Actor5 클래스
class Actor5(models.Model):
    first_name = models.CharField(max_length=20)
    last_name = models.CharField(max_length=20)
    date_of_birth = models.DateField()
    movie = models.ManyToManyField(Movie5, through='ActorMovie5', related_name='haha')
    # ActormMovie5는 중간테이블을 정의한 클래스
    # 'haha'는 역참조 시 actor5_set 대신 사용

    class Meta:
        db_table = 'actors5'

# 중간 테이블
class ActorMovie5(models.Model):
    actor = models.ForeignKey('Actor5', on_delete=models.CASCADE)
    movie = models.ForeignKey('Movie5', on_delete=models.CASCADE)

    class Meta:
        db_table = 'actors_movies5'

views.py

  • 중간테이블이 있지만 ManyToManyField를 주었기 때문에, 데이터를 불러올 때 중간테이블을 거치지 않아도 된다.

  • 중간테이블을 거치는 경우
actors = Actor.objects.all()
results = []
for actor in actors:
	# 중간테이블 actormovie 역참조
	movies = actor.actormovie_set.all()
    results.append(
    	{
    		...
    		"movies": [movie.movie.title for movie in movies]
                # movie > movie > title
    	}
    )
  • 중간테이블을 거치지 않는 경우
actors = Actor.objects.all()
results = []
for actor in actors:
	# actor가 참조한 movie 가져오기
	movies = actor.movie.all()
    results.append(
    	{
    		...
    		"movies": [movie.title for movie in movies]
                # movie > title
    	}
    )
  • views.py 전체 코드
class Actor5View(View):
    def get(self, request):
        actors = Actor5.objects.all()
        results = []
        for actor in actors:
            movies = actor.movie.all()
            results.append(
                {
                    'first_name': actor.first_name,
                    'last_name': actor.last_name,
                    'date_of_birth': actor.date_of_birth,
                    'movies': [movie.title for movie in movies]
                }
            )
        return JsonResponse({'results': results}, status=200)


class Movie5View(View):
    def get(self, request):
        movies = Movie5.objects.all()
        results = []
        for movie in movies:
            actors = movie.haha.all()    # relatied_name이 M2MField에
            # actors = movie.actor5_set.all()
            # actors = ActorMovie5.actor.all(movie=movie)
            results.append(
                {
                    'title': movie.title,
                    'release_date': movie.release_date,
                    'running_time': movie.running_time,
                    'actors': [actor.first_name + ' ' + actor.last_name for actor in actors]
                }
            )
        return JsonResponse({'results': results}, status=200)
profile
Hello World!

0개의 댓글