본문 바로가기

Python/Django

[Django] related_name은 뭐야?

728x90

데이터베이스에서 다른 테이블을 참조는 것은 Foreign Key를 사용하여 해결할 수 있다. 그렇다면 자신을 참조하고 있는 테이블을 참조하는 것은 어떻게 해야 할까? django에서는 related_name을 사용하는 것으로 이를 해결할 수 있습니다. 다음의 model.py 코드를 통해 설명해보겠습니다.

 

class Video(models.Model):
    title = models.CharField(max_length=50)
    description = models.TextField(max_length=1000, blank=True, null=True)


class Playlist(models.Model):
    title = models.CharField(max_length=50)
    description = models.TextField(max_length=1000, blank=True, null=True)
    video = models.ForeignKey(Video, null=True, on_delete=models.SET_NULL)

 

Video는 영상 매체의 정보를 담는 데이터 테이블입니다. video의 제목과 설명을 저장할 수 있습니다. Playlist는 playlist의 제목과 설명을 저장하고, Video를 참조할 수 있습니다.

 

self.video_a = Video.objects.create(title='Test1 Title')
self.playlist_a = Playlist.objects.create(title='Test1 Playlist', video=self.video_a)

 

위의 코드와 같이 예시 Video와 Playlist를 생성해줍니다. 이때 아래의 코드를 실행하면 어떻게 될까요?

 

self.playlist_a.video.title
>> 'Test1 Title'

 

출력 결과에서 확인할 수 있듯이 참조하고 있는 Video의 title을 출력하는 것을 확인할 수 있습니다.

 

self.video_a.playlist.all()
>>

 

앞서 설명한 코드와는 다르게 위의 코드는 실행되지 않습니다. Video 테이블에는 playlist라는 필드가 없기 때문입니다. 이렇게 Playlist는 Video를 참조하지만 Video는 Playlist를 참조하지 않을 때 역참조의 관계에 있다고 말합니다. 이때 django에서는 [classname]_set을 통해서 역참조의 접근을 가능하게 해 줍니다. 해당 속성을 사용하여 코드를 수정해주면 다음과 같이 변하게 됩니다.

 

self.video_a.playlist_set.all()
>> <PlaylistQuerySet [<Playlist: Playlist object (1)>]>

 

이렇게 Playlist obejct(1)이 저장되어 있는 결과를 반환해줍니다. 이때, [classname]_set 대신 사용할 수 있는 것이 바로 related_name 입니다. related_name은 models.py에서 모델 생성 시에 사용할 수 있는 속성입니다. 따라서 model 코드를 다음과 같이 수정해줍니다.

 

class Video(models.Model):
    title = models.CharField(max_length=50)
    description = models.TextField(max_length=1000, blank=True, null=True)


class Playlist(models.Model):
    title = models.CharField(max_length=50)
    description = models.TextField(max_length=1000, blank=True, null=True)
    video = models.ForeignKey(Video, null=True, related_name='playlist_featured', on_delete=models.SET_NULL)

 

realted_name = 'playlist_featured' 코드를 넣어주었습니다. 코드를 작성하였으면 playlist_set이 더 이상 동작하지 않게 됩니다. 따라서 playlist_set의 코드를 다음과 같이 수정해줍니다.

 

self.video_a.playlist_featured.all()
>> <PlaylistQuerySet [<Playlist: Playlist object (1)>]>

 

그러면 전과 같이 정상적으로 동작하는 것을 확인할 수 있습니다. 이렇게 related_name은 역참조가 필요한 다대다 또는 1대다의 관계에서 유용하게 사용할 수 있습니다. 

728x90