완숙의 블로그

models.py - QuerySet, related_name 본문

Programing Language/Web_Django

models.py - QuerySet, related_name

완숙 2020. 1. 10. 01:43

QuerySet

쿼리셋은 장고에서 가장 유용하게 사용하는 것들 중의 하나이다.

굉장히 직관적으로만 설명할 것이니 참고하길 바란다.

 

기본적으로 모델을 만들 때, 다른 모델과의 관계를 가질 수 밖에 없다.

그 관계로는 ForeignKey, ManyToManyField가 있다.

 

한명의 사용자에 여러 개의 방이 있을 수 있는 것이 ForeignKey,

한 방이 여러개의 부가시설(wifi, 전자레인지 등)을 가질 경우 ManyToManyField이다.

 

그렇다면, 방에 해당하는 User를 알 수 있을까?

 


class Room(core_models.TimeStampedModel):
    """ Room Model Definition """

    host = models.ForeignKey(
        "users.User", on_delete=models.CASCADE
    )


class User(AbstractUser):
    """ Custom User Model """

    avatar = models.ImageField(blank=True)
    gender = models.CharField(choices=GENDER_CHOICES, max_length=10, blank=True)

    bio = models.TextField(blank=True)
    birthdate = models.DateField(blank=True, null=True)
    language = models.CharField(choices=LANGUAGE_CHOICES, max_length=2, blank=True)
    currency = models.CharField(choices=CURRENCY_CHOICES, max_length=3, blank=True)
    superhost = models.BooleanField(default=False)

User 모델에는 Room에 대한 정보가 없으므로 접근할 수 없다.

 

하지만, 장고에서는 이것을 가능하게 한다. 이 보이지 않는 model을 묶어서 관리하는 것을 QuerySet이라하고, 그것을 관리하는 것을 QuerySet manager라 한다.

 

 

>>> wansik = User.objects.get(username="choiwansik")
>>> wansik
<User: choiwansik>

ansik.room_set
<django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedMana
ger object at 0x109a265f8>
>>> wansik.room_set.all()
<QuerySet [<Room: 서울에 있는 집입니다.]>

모델로 부터, 이렇게 쓸 경우 QuerySet 객체에 접근하며, 이 안에서 코드로 SQL 문처럼 정보를 가져올 수 있다.

이 때, room_set이라는 쿼리셋을 자동으로 만들어 주는 것을 알 수 있다.

 

 

Related_name

related_name은 QuerySet과 관계가 있다.

room_set과 같이 자동으로 만들어주는 이름 말고, 내가 user에서 역으로 Room에 대해 접근하고 싶을 때,

어떤 이름으로 부를 것인가에 대한 얘기이다.

 

class Room(core_models.TimeStampedModel):
    """ Room Model Definition """

    host = models.ForeignKey(
        "users.User", related_name="rooms", on_delete=models.CASCADE
    )


class User(AbstractUser):
    """ Custom User Model """

    avatar = models.ImageField(blank=True)
    gender = models.CharField(choices=GENDER_CHOICES, max_length=10, blank=True)

    bio = models.TextField(blank=True)
    birthdate = models.DateField(blank=True, null=True)
    language = models.CharField(choices=LANGUAGE_CHOICES, max_length=2, blank=True)
    currency = models.CharField(choices=CURRENCY_CHOICES, max_length=3, blank=True)
    superhost = models.BooleanField(default=False)


Room의 host에 추가적으로 파라미터를 달았다.

이제 우리는 wansik.rooms.all() 과 같이 변경된 쿼리셋 이름으로 호출 할 수 있다.

 

 

정리

ForeignKey, ManyToManyField로 설정해 놓은 곳에서,

내가 연결한 모델(user)이 주체가 되어서, 지금 연결해 놓은 모델(room)로 접근할 때,

어떤 이름으로 접근할 지 설정하는 것이다.

Comments