[Django] CRUD - 1

Jungmin Seo·2021년 6월 22일
0

Django

목록 보기
2/4

🍜 중간 테이블 사용하기

models.py

  • Actor, Movie, ActorMovie(중간테이블) 이렇게 3개의 모델클래스를 만든다.
from django.db import models
from django.db.models.base import ModelState
from django.db.models.fields import DateField, IntegerField

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.IntegerField()

    class Meta:
        db_table = 'movies'

# 중간테이블
class ActorMovie(models.Model):
    actor = models.ForeignKey('Actor', on_delete=models.CASCADE)
    movie = models.ForeignKey('Movie', on_delete=models.CASCADE)

    class Meta:
        db_table = 'actors_movies'



views.py

  • 중간테이블클래스(소문자)_set를 사용하여, actor중간테이블을 역참조한 queryset을 가져온다.
  • ex) movies = actor.actormovie_set.all()
import json

from django.http import JsonResponse
from django.views import View
from movies.models import Actor, Movie, ActorMovie


# actor의 first_name, last_name, 출연한 movies list 반환
class ActorView(View):
    def get(self, request):
        actors = Actor.objects.all()
        results = []
        for actor in actors:
            # 중간테이블 actormovie 역참조: actormovie_set
            movies = actor.actormovie_set.all()
            # 이런 방법도 있다. ActorMovie 클래스에서 불러오는 법
            # movies = ActorMovie.objects.filter(actor=actor)
            results.append(
                {
                    "first_name": actor.first_name,
                    "last_name": actor.last_name,
                    "movies": [movie.movie.title for movie in movies]
                }
            )
        return JsonResponse({'results': results}, status=200)


# movie의 title, running_time, 출연한 actors list 반환
class MovieView(View):
    def get(self, request):
        movies = Movie.objects.all()
        results = []
        for movie in movies:
            # 중간테이블 actormovie 역참조: actormovie_set
            actors = movie.actormovie_set.all()
            results.append(
                {
                    "title": movie.title,
                    "running_time": movie.running_time,
                    "actors": [actor.actor.first_name + ' ' + actor.actor.last_name for actor in actors]
                }
            )
        return JsonResponse({'results': results}, status=200)

🧂 역참조한 내용 list로 뽑기 (ex. 배우가 출연한 영화 목록)

for actor in actors:
	movies = actor.actormovie_set.all()
	results.append(
                {
                    ...
                    # movie(ActorMovie의 인스턴스)가 참조한 movie인스턴스의 title
                    "movies": [movie.movie.title for movie in movies]
                }
            )

shell에서 각 요소들 의미를 알아볼 수 있다.

>>> from movies.models import *
>>> actors = Actor.objects.all()    # Actor의 모든 인스턴스를 담은 queryset 반환
>>> actors
<QuerySet [<Actor: Actor object (1)>, <Actor: Actor object (2)>, <Actor: Actor object (3)>]>  
>>> a2 = Actor.objects.get(id=2)
>>> a2.actormovie_set.all()    # id=2인 actor 인스턴스를 참조한 ActorMovie(중간테이블)의 인스턴스를 담은 queryset 반환
<QuerySet [<ActorMovie: ActorMovie object (2)>, <ActorMovie: ActorMovie object (3)>]>  


🍝 ManyToManyField 사용하기

models.py

  • Actor3, Movie3 2개의 클래스를 만든다.
  • 참조할 클래스 외에 다른 클래스에 ManyToManyField(참조할 클래스)를 작성한다. 그러면 중간테이블이 자동으로 생성된다.
  • ex) Movie3Actor3를 참조한다.
class Movie3(models.Model):
	...
    actors = models.ManyToManyField(Actor3)

from django.db import models
from django.db.models.base import ModelState
from django.db.models.fields import DateField, IntegerField


class Actor3(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 = 'actors3'

# 참조
class Movie3(models.Model):
    title = models.CharField(max_length=50)
    release_date = models.DateField()
    running_time = models.IntegerField()
    # ManyToManyField(참조할 클래스)
    actors = models.ManyToManyField(Actor3)

    class Meta:
        db_table = 'movies3'

views.py

import json

from django.http import JsonResponse
from django.views import View
from movies.models import Actor3, Movie3

# actor의 first_name, last_name, 출연한 movies list 반환
class Actor3View(View):
    def get(self, request):
        actors = Actor3.objects.all()
        results = []
        for actor in actors:
            # actor.movie3_set.all(): actor가 Movie3를 역참조한 movie queryset 가져오기
            movies = actor.movie3_set.all()
            
            # list comprehension 대신, 리스트를 따로 만들어주는 방법
            movie_list = []
            for movie in movies:
                movie_list.append(movie.title)

            results.append(
                {
                    'first_name': actor.first_name,
                    'last_name': actor.last_name,
                    'date_of_birth': actor.date_of_birth,
                    'movies': movie_list                }
            )
            
        return JsonResponse({'results': results}, status=200)


# movie의 title, running_time, 출연한 actors list 반환
class Movie3View(View):
    def get(self, request):
        movies = Movie3.objects.all()
        results = []
        for movie in movies:
            # movie가 참조한 actors의 모든 인스턴스의 queryset 가져오기
            actors = movie.actors.all()
            actor_list = []
            for actor in actors:
                actor_list.append(actor.first_name + ' ' + actor.last_name)

            results.append(
                {
                    'title': movie.title,
                    'release_date': movie.release_date,
                    'running_time': movie.running_time,
                    'actors': actor_list
                }
            )
            
        return JsonResponse({'results': results}, status=200)
profile
Hello World!

0개의 댓글

관련 채용 정보