from django.db import models
# Create your models here.
class Movies(models.Model) :
title = models.CharField(max_length=50)
release_date = models.DateField()
running_time = models.IntegerField()
actors = models.ManyToManyField('Actors')
class Meta :
db_table = 'movies'
class Actors(models.Model) :
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
date_of_birth = models.DateField()
class Meta :
db_table = 'actors'
POST에서 조건을 나눈 다음 두 개 사이 테이블에 연결될 수 있도록 조건문을 만들어야 하는데,
우선은 단순 입력에 대한 코드만 작성
import json
from django.db.models.base import ModelBase
from django.http import JsonResponse
from django.views import View
from crud_movies.models import *
class ActorsView(View) :
def post(self, request) :
data = json.loads(request.body)
Actors.objects.create(
first_name = data['fn'],
last_name = data['ln'],
date_of_birth = data['birth'],
)
return JsonResponse({'create':'success'}, status=201)
def get(self, request) :
actors = Actors.objects.all()
result = []
for actor in actors :
movies = actor.movies_set.all()
mv_list = []
for movie in movies :
mv_list.append(
{
'title' : movie.title
}
)
result.append(
{
'first_name' : actor.first_name,
'last_name' : actor.last_name,
'movie' : mv_list
}
)
return JsonResponse({'result':result}, status=200)
class MoviesView(View) :
def post(self, request) :
data = json.loads(request.body)
Movies.objects.create(
title = data['title'],
release_date = data['r_date'],
running_time = data['r_time']
)
return JsonResponse({'create':'success'}, status=201)
def get(self, request) :
movies = Movies.objects.all()
result = []
for movie in movies :
actors = movie.actors.all()
actor_list=[]
for actor in actors :
actor_list.append(
{'name' : actor.last_name + ' ' + actor.first_name}
)
result.append(
{
'title' : movie.title,
'release_date' : movie.release_date,
'running_time' : movie.running_time,
'actors' : actor_list
}
)
return JsonResponse({'result':result}, status=200)
우선 하나만 연동해서 작성하였는데, 두 개를 연결해주기 위한 쿼리셋은 역참조를 이용하였다.
역참조 방법은 4번에서 작성
ManyToManyField()와 ForeginKey()의 차이를 비교하기 위해
개-주인과 밴드라는 클래스를 만들었다.
이름이 주인이지만 개-사람-밴드관계이며 개-주인은 FK, 사람-밴드는 M2M
class Owners(models.Model) :
name = models.CharField(max_length=50)
email = models.EmailField(max_length=150, verbose_name='주인 이메일명')
age = models.IntegerField()
class Meta :
db_table = 'owners'
class Dogs(models.Model) :
owner = models.ForeignKey('Owners', on_delete=models.CASCADE)
name = models.CharField(max_length=50)
age = models.IntegerField()
class Meta :
db_table = 'dogs'
class Bands(models.Model) :
name = models.CharField(max_length=50)
members = models.ManyToManyField('Owners')
class Meta :
db_table = 'bands'
class BandsView(View) :
def post(self, request) :
data = json.loads(request.body)
bands = Bands.objects.create(
name = data['name']
)
return JsonResponse({'result':'good'},status=201)
class OwnersView(View) :
#주인이름/주인나이/강아지이름/강아지나이
def get(self, request) :
owners = Owners.objects.all()
result = []
for owner in owners :
dogs = owner.dogs_set.all()
dogs_list=[]
for dog in dogs :
dogs_list.append({
'dog_name' : dog.name,
'dog_age' : dog.age
})
result.append({
'owner_name' : owner.name,
'owner_age' : owner.age,
'dog_info' : dogs_list
})
return JsonResponse({'reulst' : result}, status=200)
def post(self, request) :
data = json.loads(request.body)
try :
ow = Owners.objects.create(
name = data['name'],
email = data['email'],
age = data['age']
)
ow.bands_set.add(data['b_id'])
return JsonResponse({'result' : 'good'}, status=201)
except AttributeError as message :
print(message)
class DogsView(View) :
#개이름, 나이, 주인
def get(self, request) :
dogs = Dogs.objects.all()
result = []
for dog in dogs :
result.append({
'dog_name' : dog.name,
'dog_age' : dog.age,
'owner_name' : Owners.objects.get(id=dog.owner_id).name
})
return JsonResponse({'result':result}, status=200)
def post(self, request) :
data = json.loads(request.body)
try :
Dogs.objects.create(
name = data['name'],
age = data['age'],
owner_id = data['owner_id']
)
return JsonResponse({'result':'good'}, status=201)
except ValueError as message :
print('오류메시지 : ', message)
우선, 모델 구조가 바뀌어서 migrate를 해줬다.
그 결과 밴드에 대한 테이블과 bands_members라는 M2M관계에 의해 테이블이 만들어진 걸 알 수 있다.
또한 POST 요청을 통해 밴드에 데이터를 생성했다.
try :
ow = Owners.objects.create(
name = data['name'],
email = data['email'],
age = data['age']
)
ow.bands_set.add(data['b_id'])
이건 위의 views.py의 일부분을 가져온건데, owner 데이터를 생성할 때
생성된 객체를 이용해 밴드를 역참조하여 중간테이블에 데이터를 넣어줬다.
이렇게 테이블에 데이터가 생성된 걸 확인할 수 있는데,
중간테이블을 거치지 않고 한 번에 역참조하여 데이터를 넣어줄 수 있는 것. 이게 가장 큰 장점이다.
또한 역참조로 데이터를 넣을 수 있는 만큼 역참조로 가져올 수 있다.
Owners와 Bands가 M2M 관계인 걸 이용해 역참조를 하여 데이터를 가져올 수 있다.
ow라는 변수에 id=12인 객체를 가져오고, 그 객체를 참조하는 객체인 Bands를 소문자로써서 뒤에 _set을 붙여준다.
그러면 쉽게 나를 참조하는 데이터에 접근이 가능하다.
직접 코딩을 해봤는데, 이제 막 배운 단계라 그런지 이게 그렇게 편한가? 라는 생각은 크게 와닿지 않았다.
앞으로 계속 해보며 적응해 나가야겠다.
물론 역참조 방법은 진짜 혁명이긴 했다.