[Django] Reverse Relations & Related Name

hukim·2020년 10월 29일
0

Django

목록 보기
6/12
post-custom-banner

정참조와 역참조 객체 서로 호출하기

User 테이블과 사용자의 직업인 Occupation 테이블이 있다고 가정합니다.

두 테이블은 N:1 관계에 있으며, User 객체가 Occupation 객체를 참조하고 있습니다.

User가 Occupation을 선택하여 입사 원서를 작성한다고 가정하겠습니다.

class User(models.Model):
	name 	  = models.CharField(max_length = 50)
    	job       = models.ForeignKey('Occupation', on_delete = models.CASCADE)
        create_at = models.DateTimeField(auto_now_add = True)
        
class Occupation(models.Model):
	name = models.CharField(max_length = 50)

User 객체는 Occupation 객체를 정참조 하고 있으므로 속성 이름으로 바로 접근할 수 있습니다.

user = User.objects.get(id = 1)
user.job.name
>>> 'Developer'

그렇지만 반대로 Occupation 객체는 User 객체를 역참조 하고 있으므로 바로 접근이 불가능합니다.

이렇게 역참조 관계에 있을 때는 [classname]_set이라는 속성을 사용하여 접근해야 한다.

job = Occupation.objects.get(id = 1)
people = job.user_set.all()
>>> <QuerySet[<Object User Object(1)>, <QuerySet[<Object User Object(2)>

이 때, user_set대신 사용할 수 있는 것이 related_name입니다.

User 클래스를 정의할 때, 정참조 하고 있는 Occupation 클래스의 인스턴스에서 어떤 명칭으로 거꾸로 호출당할 지를 정해주는 이름입니다.

class User(models.Model):
	name 	  = models.CharField(max_length = 50)
    	job       = models.ForeignKey(
        	'Occupation', 
        	on_delete = models.CASCADE,
       		related_name = 'appliers'
        )
        create_at = models.DateTimeField(auto_now_add = True)
        
class Occupation(models.Model):
	name = models.CharField(max_length = 50)

User 객체를 정의할 때, job의 속성에 Occupation 객체가 연결되어 정참조 하고 있습니다.
Occupation 객체의 인스턴스와 연결되어 있는 User 객체를 거꾸로 불러올 때, appliers라는 이름으로 부르기 위해 job 속성에 related_name = 'appliers'를 지정해주었습니다.

job1   = Occupation.objects.get(id = 1)
people = job1.appliers.all()
>>> <QuerySet[<Object User Object(1)>, <Object User Object(2)>]>
class User(models.Model):
    name       = models.CharField(max_length = 50)
    job	       = models.ForeignKey('Occupation', on_delete = models.CASCADE)
    choice_2nd = models.ForeignKey('Occupation', on_delete = models.CASCADE, null = True)
    created_at = models.DateTimeField(auto_now_add = True)
    	
class Occupation(models.Model):
    name = models.CharField(max_length = 50)

한 클래스에서 서로 다른 두 컬럼이 같은 테이블을 참조하는 경우

지원자가 필수로 신청한 occupatoin외에 2지망인 occupation도 받는 경우에는 위와 같은 모델이 된다.

위의 경우에는 Occupation 객체를 정참조 하고 있는 컬럼이 job과 choice_2nd 두개 이므로 그저 user_set 속성만으로는 자신을 바라보고 있는 두 User 객체 가운데 어떤 속성에 접근해야 할 지 알 수가 없기 때문입니다.

즉, developer를 1지망으로 고른 사람들의 목록을 가져와야 할 것인지, 2지망으로 고른 사람들의 목록을 가져와야할 지 알 수가 없습니다.

class User(models.Model):
    name = models.CharField(max_length = 50)
    job	 = models.ForeignKey( 
            'Occupation',
            on_delete    = models.CASCADE,
            related_name = 'appliers' ------------------------- [Key Point !]
        )
    choice_2nd  = models.ForeignKey(
            'Occupation',
            on_delete    = models.CASCADE,
            null         = True
            related_name = 'second_appliers'
        )
    created_at	= models.DateTimeField(auto_now_add = True)

그럴 경우 related_name으로 구분해서 호출할 수 있게끔 작성해줍니다.

post-custom-banner

0개의 댓글