ManyToManyField
crud(2)owner-dogテーブルで1:N関係データベースのBackend APIを実現した.今回はN:N関係テーブルでManyToManyFieldを用いてBackend APIを実装する.
これはN:N関係なので、ActorとMovieテーブルをForeignKeyに接続する中間テーブルを作成します.Pyと書きました.
したがって、ForeignKeyではなくManyToManyFieldを使用すると、Djangoで自動的に中間テーブルを作成する中間テーブルを使用せずに、N:N関係を直接定義してデータを参照できます.
ManyToManyFieldを使用して再モデリングします.Pyと書きました.
throughを使用すると、中間テーブルを通過しないN:N関係のテーブルで、相対テーブルを直接参照できます.
また、related nameが設定されている場合、参照するモデルで逆参照を行う場合は、参照用に直感的な名前に設定できます.
Djangoでは、関連するnameの設定が必要で、同じクラスのプロパティでは、関連するnameを設定せずに互いに同じモデルを参照すると、移行は発生せず、エラーが発生します.
私の場合もエラーが発生し、migartinにはならず、関連するnameを設定してスムーズに移行しました.
次に、Database Tableを作成し、各Tableにデータを入力しようとします.
list理解ではactormoviesを参照せずに直接参照することができ,コードの長さが短くなり,可読性が良くなると判断できる.
Model
これはN:N関係なので、ActorとMovieテーブルをForeignKeyに接続する中間テーブルを作成します.Pyと書きました.
from django.db import models
# 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=45)
release_date = models.DateField()
running_time = models.IntegerField()
class Meta:
db_table = 'movies'
class Actor_Movie(models.Model):
actor = models.ForeignKey('Actor', on_delete=models.CASCADE)
movie = models.ForeignKey('Movie', on_delete=models.CASCADE)
class Meta:
db_table = 'actor_movies'
上記のコードのように、中間テーブルを使用してviewロジックを作成すると、コードが長すぎたり、可読性が低下したり、不要な長すぎたりします.また、値を追加またはロードする場合は、中間テーブルを使用します.したがって、ForeignKeyではなくManyToManyFieldを使用すると、Djangoで自動的に中間テーブルを作成する中間テーブルを使用せずに、N:N関係を直接定義してデータを参照できます.
ManyToManyFieldを使用して再モデリングします.Pyと書きました.
from django.db import models
# 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()
movies = models.ManyToManyField('Movie', through='Actor_Movie', related_name='actors')
class Meta:
db_table = 'actors'
class Movie(models.Model):
title = models.CharField(max_length=45)
release_date = models.DateField()
running_time = models.IntegerField()
class Meta:
db_table = 'movies'
class Actor_Movie(models.Model):
actor = models.ForeignKey('Actor', on_delete=models.CASCADE)
movie = models.ForeignKey('Movie', on_delete=models.CASCADE)
class Meta:
db_table = 'actor_movies'
中間表は省略できますが、中間表はcolumnを記入する必要がある場合があるので残しておきます.throughを使用すると、中間テーブルを通過しないN:N関係のテーブルで、相対テーブルを直接参照できます.
また、related nameが設定されている場合、参照するモデルで逆参照を行う場合は、参照用に直感的な名前に設定できます.
Djangoでは、関連するnameの設定が必要で、同じクラスのプロパティでは、関連するnameを設定せずに互いに同じモデルを参照すると、移行は発生せず、エラーが発生します.
私の場合もエラーが発生し、migartinにはならず、関連するnameを設定してスムーズに移行しました.
次に、Database Tableを作成し、各Tableにデータを入力しようとします.
View
import json
# from django.shortcuts import render
from django.http import JsonResponse
from django.views import View
from movies.models import Actor, Movie, Actor_Movie
# Create your views here.
class ActorView(View):
def get(self, request):
actors = Actor.objects.all()
# movies = Movie.objects.all()
# actor_movies = Actor_Movie.objects.all()
results = [{
"first_name": actor.first_name,
"last_name" : actor.last_name,
"movie" : [{
"title" : movie.title
} for movie in actor.movies.all()]
} for actor in actors]
# results = []
# for actor in actors:
# for actor_movie in actor_movies.filter(actor_id=actor.id):
# movie_list = []
# movie_list.append(Movie.objects.get(id=actor_movie.movie_id).title)
# results.append(
# {
# "first_name" : actor.first_name,
# "last_name" : actor.last_name,
# "title" : movie_list
# }
# )
return JsonResponse({'reults': results}, status=200)
class MovieView(View):
def get(self, request):
movies = Movie.objects.all()
results = [{
"title" : movie.title,
"running_time" : movie.running_time,
"actor" : [{
"first_name" : actor.first_name,
"last_name" : actor.last_name
} for actor in movie.actors.all()]
} for movie in movies]
return JsonResponse({'reults': results}, status=200)
もう中间テーブルとMovieテーブルを使わなくてもいいので、コメント処理をしてくれました.list理解ではactormoviesを参照せずに直接参照することができ,コードの長さが短くなり,可読性が良くなると判断できる.
Reference
この問題について(ManyToManyField), 我々は、より多くの情報をここで見つけました https://velog.io/@cghy4862/ManyToManyFieldテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol