참조 django
https://docs.djangoproject.com/en/3.1/topics/db/examples/many_to_many/
영화와 배우의 관계를 나타내는 데이터 모델을 작성하고 불러오는 로직을 짜봐라
배우 A는 영화a, 영화b 에 출연 가능하며
영화a 에는 배우 A, 배우 B가 출연할 수 있다.
지금은 단순한 예제이지만 실제로 쓰이는
Many to Many 의 데이터 관계에는 테이블이 복잡하게 얽혀 있을 수 있다.
Model
class Actor(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
date_of_birth = models.DateField()
movie = models.ManyToManyField("Movie", related_name="movies")
class Meta:
db_table = "actor"
class Movie(models.Model):
title = models.CharField(max_length=100)
release_date = models.DateField()
running_time = models.IntegerField()
class Meta:
db_table = "movie"
View
일단 view 로직을 짜기 전에 shell에서 찍어보자
actor 객체에서 movie
movie 객체에서 actor 객체는?
원래라면 obj_set. 을 통해 접근해야하지만 Actor model을 작성할때 ManyToManyField에 related name을 부여해줬으므로 해당 related name으로 접근가능하다. (해당 model에서 부여된 related name은... 할 말이 없다 movies라고 주다니 뇌절)
마지막은 기왕 부르는거 깔끔하게 부르고 싶어봐서 저렇게 해봤다
class ActorView(View):
def get(self, request):
results = []
actors = Actor.objects.all()
for actor in actors:
movies = actor.movie.all()
print("actor:", actor.first_name)
results.append(
{
"first_name": actor.first_name,
"last_name": actor.last_name,
"date_of_birth": actor.date_of_birth,
"movie": [movie.title for movie in movies],
}
)
return JsonResponse({"resutls": results}, status=200)
class MovieView(View):
def get(self, request):
results = []
movies = Movie.objects.all()
for movie in movies:
actors = movie.movies.all()
results.append(
{
"title": movie.title,
"release_date": movie.release_date,
"runnig_time": movie.running_time,
"actors": [actor.first_name for actor in actors],
}
)
return JsonResponse({"resutls": results}, status=200)
shell 로 찍어본 로직 view page 로 옮기면 이렇게 작성할 수 있다.
httpi를 통해 request 날려보자
MovieView
ActorView
이렇게 ManyToManyField 를 사용하면 객체의 접근이 용이하다.
그리고 relataed name 과
다음은 멍멍이와 주인의 상관관계에 대한 데이터 모델이다
class Owner(models.Model):
name = models.CharField(max_length=20)
email = models.CharField(max_length=300)
age = models.IntegerField()
class Meta:
db_table = "owner"
class Dog(models.Model):
owner = models.ForeignKey("Owner", on_delete=CASCADE)
name = models.CharField(max_length=45)
age = models.IntegerField()
class Meta:
db_table = "dog"
주인이 여러마리의 멍멍이를 키울 수 있으니 멍멍이가 owner의 foreignkey 를 가지고 있다.
view 로직이다.
class OwnerView(View):
def post(self, request):
data = json.loads(request.body)
Owner.objects.create(
name = data["owner_name"],
email = data["owner_email"],
age = data["owner_age"]
)
return JsonResponse({'MESSAGE':'SUCCESS'}, status=201)
def get(self, request):
owners = Owner.objects.all()
results = []
for owner in owners:
dogs_list = []
dogs = Dog.objects.filter(owner=owner)
for dog in dogs:
dogs_list.append({
"dog_name" : dog.name,
"dog_age" : dog.age,
})
results.append({
"owner_name" : owner.name,
"owner_email" : owner.email,
"owner_age" : owner.age,
"dog" : dogs_list,
})
return JsonResponse({'resutls':results}, status=200)
class DogView(View):
def post(self, request):
data = json.loads(request.body)
Dog.objects.create(
name = data["dog_name"],
age = data["dog_age"],
owner = Owner.objects.create(
name=data["owner_name"],
email=data["owner_email"],
age=data["owner_age"]
)
)
return JsonResponse({'MESSAGE':'SUCCESS'}, status=201)
def get(self, request):
dogs = Dog.objects.all()
results=[]
for dog in dogs:
results.append(
{
"dog_name" : dog.name,
"dog_age" : dog.age,
"owner_name": dog.owner.name,
})
return JsonResponse({'resutls':results}, status=200)