Multi Table Inheritance

dooh kim·2020년 9월 2일
0

model


from django.db import models


class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=100, blank=True)


class Restaurant(Place):
    hot_dogs = models.BooleanField(default=False)
    pizza = models.BooleanField(default=False)

    def __str__(self):
        return f'{self.name} (핫도그: {self.hot_dogs}, 피자: {self.pizza}'

jupyter notebook

import os 
os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true"

Place.objects.all().delete()
Restaurant.objects.all().delete()

p1 = Place.objects.create(name='성수역')
r1 = Restaurant.objects.create(name='빽다방', hot_dogs=True)


place_id = r1.place_ptr_id
p2 = Place.objects.get(pk=place_id)
p2.restaurant

Place model을 상속받은 Restaurant model은 자동적으로
One To One으로 Place와 관계를 같게 된다.

그래서
r1이 만들어 질 경우 자동적으로 Place 모델 인스턴스로
빽다방이라는 장소 컬럼 데이터가 생성 된다.

from django.db import models


class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=100, blank=True)

    class Meta:
        # admin 페이지에 클래스 이름 재설정
        verbose_name = '장소'
        verbose_name_plural = '장소 목록'

    def __str__(self):
        return self.name


class Restaurant(Place):
    # 명시적으로 Multi-table inheritance를 구성하는 OneToOneField를 지정
    place_ptr = models.OneToOneField(Place, parent_link=True, related_name='restaurant',
                                     related_query_name='restaurant_by_oto',
                                     on_delete=models.CASCADE)
    # 기본값을 사용할 경우, Place의 related_query_name이 겹칠 수 있는 ManyToMany를 선언
    near_places = models.ManyToManyField(Place,
                                         related_query_name='restaurant_by_near_places',
                                         related_name='restaurant_set')
    hot_dogs = models.BooleanField(default=False)
    pizza = models.BooleanField(default=False)

    def __str__(self):
        return f'{self.name} (핫도그: {self.hot_dogs}, 피자: {self.pizza}'

related_name

  • 역참조 할 경우 사용되는 옵션이다

for example)
p1, p2, p3 = [Place.objects.create(name=name) for name in '성수역,강남역,홍대입구역'.split(',')]

r1, r2, r3 = [Restaurant.objects.create(name=name) for name in '성수 빽다방, 강남 빽다방, 홍대입구 빽다방'.split(',')]

p1.restaurant_set.all()

이런식으로 접근 가능

related_query_name

filter 메소드를 사용할 경우에 쓰인다.

r1.near_places.add(p1, p2)
r1.near_places.all()

Place.objects.filter(restaurant_by_near_places__name__contains='성수').values_list('pk')

profile
testify to the light

0개의 댓글