models.py
파일 만들기#movies.models.py
from django.db import models
from django.db.models.deletion import CASCADE
from django.db.models.fields import DateField
from django.db.models.fields.related import ManyToManyField
# Create your models here.
class Actor(models.Model): #배우
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
date_of_birth = models.DateField()
class Meta:
db_table = 'actors'
class Movie(models.Model): # 영화
title = models.CharField(max_length=20)
release_date = models.DateField()
running_time = models.DecimalField(max_digits=6,decimal_places=2)
class Meta:
db_table = "movies"
#배우- 영화 중간 테이블
class Actormovie(models.Model):
actor = models.ForeignKey('Actor',on_delete=CASCADE) #actor_id
movie = models.ForeignKey('Movie',on_delete=CASCADE) #actor_id
class Meta:
db_table = "actors_movies"
1. 배우의 이름, 성, 그리고 출연한 영화 제목 목록
from django.db.models.fields.related import ManyToManyField
from django.shortcuts import render
import json
from django.http import JsonResponse
from django.views import View
from movies.models import Actormovie, Actor, Movie , Actor2, Movie2
class ActorView(View):
def get(self,request):
actors = Actor.objects.all()
results = []
for actor in actors:
actormovies = actor.actormovie_set.all() #역참조하기 : 테이블명소문자_set
movie_list = []
for actormovie in actormovies:
movie_info = {
'title' : actormovie.movie.title,
}
movie_list.append(movie_info)
results.append(
{
"first_name" : actor.first_name,
"last_name" : actor.last_name,
"title" : movie_list #출연한 영화 제목 목록
}
)
return JsonResponse({'results': results}, status = 200)
2. 영화의 제목, 상영시간, 출연한 배우 목록 (이름만)
class MovieView(View):
def get(self, request):
movies = Movie.objects.all()
results = []
for movie in movies:
actormovies = movie.actormovie_set.all() #역참조
actor_list = []
for actormovie in actormovies:
actor_info = {
'first_name' : actormovie.actor.first_name,
'last_name' : actormovie.actor.last_name,
}
actor_list.append(actor_info)
results.append(
{
"title" : movie.title,
"running_time" : movie.running_time,
# 출연한 배우 목록
"name" : actor_list
}
)
return JsonResponse({'results': results },status=200 )
models.py
만들기ManyToManyField
을 만들었기 때문에 models.py
에서 중간테이블을 직접 만들지 않고 django에서 중간테이블을 알아서 만들어줌. 하지만 데이터베이스에서 수정,관리 할수 없기 때문에 모델 클래스 중간테이블을 따로 만들어주는 것이 좋음. #movies/models.py
class Movie2(models.Model): # 영화
title = models.CharField(max_length=20)
release_date = models.DateField()
running_time = models.DecimalField(max_digits=6,decimal_places=2)
class Meta:
db_table = "movies2"
class Actor2(models.Model): #배우
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
date_of_birth = models.DateField()
movie = models.ManyToManyField(Movie2, through='Movie2Actor2')
# 만약 중간테이블안만들고 manytomany 사용하면 데이터 베이스에 저절로 중간테이블을 만드나, 내용을 수정,입력할 수 없으니 밑의 클래스를 하나 더만들어 직접 fk로 연결해 만들어 주는 것이 좋음.
class Meta:
db_table = 'actors2'
# manytomany필드만 사용하고 fk를 사용안하면 migrions했을때 설계도에 아무것도 생기지 않음.
class Movie2Actor2(models.Model):
actor2 = models.ForeignKey('Actor2',on_delete=CASCADE) #actor2_id
movie2 = models.ForeignKey('Movie2',on_delete=CASCADE) #actor2_id
class Meta:
db_table = 'actors2_movies2'
1. 배우의 이름, 성, 그리고 출연한 영화 제목 목록
class ActorView2(View):
def get(self,request):
actors = Actor2.objects.all() # 쿼리셋 반환, all(),get()같은 메소드들을 포함하는 클래스를 매니저라고 부름, 여기서는 objects가 매니저
results = []
for actor in actors:
movies = actor.movie.all() #참조, 여기서는 movie가 매니저
movie_list = []
for movie in movies:
movie_info = {
'title' : movie.title,
}
movie_list.append(movie_info)
results.append(
{
"first_name" : actor.first_name,
"last_name" : actor.last_name,
"title" : movie_list #출연한 영화 제목 목록
}
)
return JsonResponse({'results': results },status=200 )class ActorView2(View):
def get(self,request):
actors = Actor2.objects.all() # 쿼리셋 반환, all(),get()같은 메소드들을 포함하는 클래스를 매니저라고 부름, 여기서는 objects가 매니저
results = []
for actor in actors:
movies = actor.movie.all() #참조, 여기서는 movie가 매니저
movie_list = []
for movie in movies:
movie_info = {
'title' : movie.title,
}
movie_list.append(movie_info)
results.append(
{
"first_name" : actor.first_name,
"last_name" : actor.last_name,
"title" : movie_list #출연한 영화 제목 목록
}
)
return JsonResponse({'results': results },status=200 )
2. 영화의 제목, 상영시간, 출연한 배우 목록 (이름만)
class MovieView2(View):
def get(self,request):
movies = Movie2.objects.all()
results = []
for movie in movies:
actors = movie.actor2_set.all() # 역참조
actor_list = []
for actor in actors:
actor_info = {
'first_name' : actor.first_name,
'last_name' : actor.last_name,
}
actor_list.append(actor_info)
results.append(
{
"title" : movie.title,
"running_time" : movie.running_time,
# 출연한 배우 목록
"name" : actor_list
}
)
return JsonResponse({'results': results },status=200 )
models.py
에서 ManyToManyField
를 Actor2라는 클래스 안에 만들어 줬기 때문에 Actor2가 Movie2를 참조하기 때문에 Movie2에서 Actor2를 갖고오려면 역참조 해야한다. #models.py
class Actor2(models.Model): #배우
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
date_of_birth = models.DateField() #후에 형태는 "1998-01-01"
movie2 = models.ManyToManyField(Movie2) # Actor2가 Movie2를 참조한다.
ManyToManyField
없이 Foreign Key 로만 이루어진 중간테이블을 선언하여 M2M 를 구현해도 되는데,ManyToManyField
를 사용하면 어떤 이점이 있는지?
+) related_name을 사용할 경우
- 한 테이블의 속성 두개가 한 테이블을 참조한다고 했을때. 만약 역참조를 한다면 어떤 속성을 역참조 해야하는지 모르므로 그때 related_name을 설정해 어떤 속성을 사용할 것인지 정해줘야한다. ,,,,,(,,?)