TIL33 - Actors & Movies usnig Django

Kiyong Lee·2021년 9월 15일
0

Django

목록 보기
9/35
post-custom-banner

Actors & Movies usnig Django


1. 문제


2. 코드


2-1. models.py

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'

2-2. views.py

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)

3. get 조회 결과

우선 하나만 연동해서 작성하였는데, 두 개를 연결해주기 위한 쿼리셋은 역참조를 이용하였다.
역참조 방법은 4번에서 작성


4. ManyToManyField를 왜 쓸까?

ManyToManyField()와 ForeginKey()의 차이를 비교하기 위해
개-주인과 밴드라는 클래스를 만들었다.
이름이 주인이지만 개-사람-밴드관계이며 개-주인은 FK, 사람-밴드는 M2M


4-1. models.py

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'

4-2. views.py

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을 붙여준다.

그러면 쉽게 나를 참조하는 데이터에 접근이 가능하다.


5. 후기

직접 코딩을 해봤는데, 이제 막 배운 단계라 그런지 이게 그렇게 편한가? 라는 생각은 크게 와닿지 않았다.

앞으로 계속 해보며 적응해 나가야겠다.

물론 역참조 방법은 진짜 혁명이긴 했다.

profile
ISTJ인 K-개발자
post-custom-banner

0개의 댓글