이전 포스팅에서 Relationships에 대해 알아봤습니다.
https://android-developer.tistory.com/85
[기초] 파이썬 장고 REST API - Relationship 설정하기
이전 포스팅에서 Model Serializers를 사용하여 Model을 사용하는 방법에 대해 알아봤습니다. https://android-developer.tistory.com/84 [기초] 장고 REST API 프레임워크 - Model Serializer 이번 포스팅에서는 Model을 만
android-developer.tistory.com
이번에는 다수의 Model을 연결하는 Nested Relationships에 대해 알아보겠습니다.
- Relationships를 사용하여 특정 아이템을 서로 묶기
- Nested Relationships 사용하기
Relationships를 사용하여 특정 아이템을 서로 묶기
이전 포스팅에서 저희는 기존에 있는 Movies라는 Model 이외에 StreamPlatform이라는 Model을 새롭게 만들었습니다.
Nested Relationships를 적용하기 전에 Movies 와 StreamPlatform 사이에 Relationships를 만들어보겠습니다.
먼저 Movie Model을 다음과 같이 변경합니다.
class StreamPlatform(models.Model):
    # Model(=DB)에서 사용할 Column 정의
    id = models.BigAutoField(primary_key=True)
    name = models.CharField(max_length=50)
    about = models.TextField(max_length=200)
    website = models.URLField(max_length=100)
    def __str__(self):
        return self.name
class Movie(models.Model):
    # Model(=DB)에서 사용할 Column 정의
    id = models.BigAutoField(primary_key=True)
    name = models.CharField(max_length=50)
    description = models.TextField(max_length=200)
    # StreamPlatform은 여러 개의 Movie를 가질 수 있음
    platform = models.ForeignKey(StreamPlatform, on_delete=models.CASCADE, related_name='movie')
    active = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    def __str__(self):
        return self.name
ForeignKey를 사용하여 StreamPlatform을 아이템으로써 가질 수 있도록 합니다.
그러면 admin에서 다음과 같은 항목이 추가된 것을 확인할 수 있습니다.
admin - Movies에 들어가서 아이템을 추가해보면

사진과 같이 Platform 부분이 생성된 것을 알 수 있습니다.
해당 Platform에서 다음과 같이 생성해놓은 Platform을 선택할 수 있게됩니다.

Platform을 선택하면 다음과 같이 Movies 아이템에서 Platform의 id로 값이 표시되어있는 것을 알 수 있습니다.


Nested Relationships 사용하기
지금까지의 과정으로 Movie와 StreamPlatform이라는 2개의 model을 생성했습니다.
이름에서 알 수 있다시피 StreamPlatform은 스트리밍 플랫폼이며 이는 많은 Movie를 가질 수 있음을 의미합니다.
즉, StreamPlatform Model은 Movie Model을 가질 수 있습니다.
이를 Nested Relationships라고 합니다.
공식 문서는 다음과 같습니다.
Serializer relations - Django REST framework
relations.py Data structures, not algorithms, are central to programming. — Rob Pike Relational fields are used to represent model relationships. They can be applied to ForeignKey, ManyToManyField and OneToOneField relationships, as well as to reverse re
www.django-rest-framework.org
지금까지 했던 프로그램에서 예를 들면 다음과 같습니다.
먼저 models.py에서 지정한 related_name을 확인합니다.
# 해당 앱/models.py
from django.db import models
class StreamPlatform(models.Model):
    # Model(=DB)에서 사용할 Column 정의
    id = models.BigAutoField(primary_key=True)
    name = models.CharField(max_length=50)
    about = models.TextField(max_length=200)
    website = models.URLField(max_length=100)
    def __str__(self):
        return self.name
class Movie(models.Model):
    # Model(=DB)에서 사용할 Column 정의
    id = models.BigAutoField(primary_key=True)
    name = models.CharField(max_length=50)
    description = models.TextField(max_length=200)
    # StreamPlatform은 여러 개의 Movie를 가질 수 있음
    platform = models.ForeignKey(StreamPlatform, on_delete=models.CASCADE, related_name='movielist')
    active = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    def __str__(self):
        return self.name
위 코드에서 Movie Model에서 StreamPlatform과 연결한 이름(related_name)을 찾습니다.
이를 serializers.py에서 활용합니다.
from rest_framework import serializers
from watchlist_app.models import Movie, StreamPlatform
        
class MovieSerializer(serializers.ModelSerializer):
    len_name = serializers.SerializerMethodField()
    
    class Meta:
        model = Movie
        # 모든 Field를 사용하게 한다.
        fields = "__all__"
        # 사용하고 싶은 Field를 지정하고 싶으면 다음과 같이 한다
        # fields = ['id', 'name', 'description']
        
        # 또는 특정 Field만 제외하고싶다면 다음과 같이 한다.
        # exclude = ['activity']
        
    def get_len_name(self, object):
        return len(object.name)
        
    def validate(self, data):
        if data['name'] == data['description']:
            raise serializers.ValidationError("이름과 내용이 같아선 안됩니다.")
        else:
            return data
    
    # field level validation
    # validate_필드 이름으로 만들면 자동으로 오버라이드 해준다.
    def validate_name(self, value):
        if len(value) < 2:
        	raise serializers.ValidationError("이름이 너무 짧습니다.")
        else :
            return value
        
class StreamPlatfromSerializer(serializers.ModelSerializer):
	# related_name에서 정의한 이름과 똑같은 이름으로 변수를 정의한다.
    movielist = MovieSerializer(many=True, read_only=True)
    
    class Meta:
        model = StreamPlatform
        fields = "__all__"
여기까지 하고 Build 해보면 다음과 같은 결과를 볼 수 있다.

StreamPlatform Model 안에 movielist 항목이 생긴 것을 알 수 있다.
각각의 스트리밍 플랫폼이 어떤 movie를 갖고 있는지 확인할 수 있다.
'파이썬(Python) > 장고(Django)' 카테고리의 다른 글
| [기초] 파이썬 장고 REST API - Serializer relations (2) | 2024.02.18 | 
|---|---|
| [기초] 파이썬 장고 REST API - Relationship 설정하기 (1) | 2024.02.05 | 
| [기초] 장고 REST API 프레임워크 - Model Serializer (0) | 2024.02.05 | 
| [기초] 파이썬 장고 REST API 프레임워크 - Validation (1) | 2024.02.02 | 
| [기초] 파이썬 장고 REST API 프레임 워크 - Class-based Views (0) | 2024.02.01 | 
"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."
 
										
									 
										
									 
										
									 
댓글