Django - M to M relationship


参照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アクセスは必要ですが、ManyToManyFieldにはマクロベースモデルの作成時に関連名が付与されているため、関連名を使用してアクセスできます.△このモデルに付けられた関連名称は…何とも言えない映画で、頭が痛い.

最後に歌うからにはきれいに歌いたい
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で印刷して「論理ビュー」ページに移行すると、このように記述できます.

request - response


httpiによるリクエストの送信
MovieView

ActorView

これにより、ManyToManyFieldを使用すると、オブジェクトに簡単にアクセスできます.
関係名と

ForengKeyを使ったらどうしますか?


次は犬と飼い主の関係に関するデータモデルです
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"
飼い主は子犬を何匹も飼うことができ、子犬には飼い主のforeignkeyがいる.

これはビューロジックです.
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)