Django 3

김기현·2022년 2월 4일
1

django

목록 보기
3/8
post-thumbnail

이어서 onetomany, manytoone, manytomany관계와 ForeignKey에 대해 알아보겠습니다.

ForeignKey with ManyToOne Field

외래키(Foreign Key)란 테이블의 필드 중에서 다른 테이블의 행과 식별할 수 있는 키를 의미합니다.

다음과 같은 테이블은 너무 많은 열(column)이 추가되어 효율적이지 못한 구조입니다.

너무 많은 열과 데이터로 조회하는데 비교적 오랜시간이 소요될 수 있습니다. 그래서 다음 아래의 사진과 같이 두개의 테이블로 나누고 연결고리를 만들어줍니다.


결론적으로 두 테이블을 연결할 수 있도록 하는 것이 Foreign Key의 역할입니다.

class Room(core_models.TimeStampedModel):
	host = models.ForeignKey(
        "users.User", related_name="rooms", on_delete=models.CASCADE, null=True
    )
    room_type = models.ForeignKey(
        "RoomType", related_name="rooms", on_delete=models.SET_NULL, null=True
    )

외래키를 작성할 때 필수적으로 포함되어야할 매개변수는 참조할 테이블, 개체 관계에 사용할 이름, 개체 삭제시 수행할 동작 등 입니다.

참조할 테이블은 외래키에서 어떤 테이블을 참조할지 의미합니다. 예제에서는 user 폴더의 User 테이블, RoomType 테이블입니다.
개체 관계에 사용할 이름(related_name)은 추상 모델에서 관계를 정의할 때 사용될 이름을 의미합니다. 예제에서는 rooms입니다.
개체 삭제시 수행할 동작(on_delete)은 외래키(ForeignKey)가 바라보는 테이블의 값이 삭제될 때 수행할 방법을 지정합니다. 예를 들어 유저가 삭제되었을 때 남아있는 방을 지울 것인지, 에러를 띄워 방을 보호할 것인지 등입니다.

이는 자신과 ManyToOne(다대일 관계)에 해당하는 객체만 적용될 수 있습니다.

ManyToMany Field

다음의 코드는 여러개의 타입을 여러 방에 연결하도록 하는 ManyToMany 필드입니다.

class Amenity(AbstractItem):
    class Meta:
        verbose_name_plural = "Amenities"
        
class Facility(AbstractItem):
    class Meta:
    	#abstract = True
        verbose_name_plural = "Facilities"

class HouseRule(AbstractItem):
    class Meta:
        verbose_name = "House Rule"
class Room(core_models.TimeStampedModel):
    amenities = models.ManyToManyField("Amenity", related_name="rooms", blank=True)
    facilities = models.ManyToManyField("Facility", related_name="rooms", blank=True)
    house_rules = models.ManyToManyField("HouseRule", related_name="rooms", blank=True)

이 관계에서 두 모델 중 어느 쪽에서 선언해도 상관없습니다. blank=True 옵션을 걸어준 이유는 하나도 지정안할 수 도 있도록 하기 위함입니다.

추가로 meta class는 class 안의 class로 verbose_name(복수), ordering 등을 지정할 수 있고, abstract = true해두면 model이지만 데이터베이스에 나타나지 않습니다.

OneToOne Field

OneToOneField 는 1:1 관계를 의미합니다.

class User(AbstractBaseUser):
  # 생략

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)

위 코드는 django 에 기본적으로 정의되어 있는 User 모델과 이를 커스튬하여 새로 만드는 Profile 모델을 연결한 모델입니다.

profile
피자, 코드, 커피를 사랑하는 피코커

0개의 댓글