Django Polymorphic Associations Tutorial
12981 단어 데이터베이스Rails파이썬polymorphic장고
소개
내 기사 Django가 다른 Polymorphic과 거동이 다른 건 에서 Django의 PolymorphicModel이 소위 폴리모픽 관련과 다른 것을 기사로 했습니다.
이번에는 "그럼 Django에서 폴리모픽 관련을 구현하려면 어떻게 할까"라는 점에 대해 설명합니다.
환경
목표
RailsGuide의 PolymorphicAssociations 장에서는 다음과 같이 폴리모픽 관련이 구현되어 있습니다.
class Picture < ApplicationRecord
belongs_to :imageable, polymorphic: true
end
class Employee < ApplicationRecord
has_many :pictures, as: :imageable
end
class Product < ApplicationRecord
has_many :pictures, as: :imageable
end
이것에 다음의 ER과 같은 속성을 갖게 한 Model을 구현하는 것을 목표로 합니다.
coontent_type
는 어떤 테이블과 연관되어 있는지를 나타내고, object_id
는 어떤 레코드가 연관되어 있는지를 나타냅니다.구현
모델링
from django.db import models
from django.contrib.contenttypes.models import ContentType
class Picture(models.Model):
object_id = models.IntegerField(db_index=True)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
file_name = models.CharField()
class Employee(models.Model):
name = models.CharField()
email = models.EmailField()
class Product(models.Model):
name = models.CharField()
price = models.IntegerField()
Imageable 클래스 구현
from django.db import models
from django.contrib.contenttypes.fields import GenericRelation, GenericForeignKey
from django.contrib.contenttypes.models import ContentType
class Picture(models.Model):
object_id = models.IntegerField(db_index=True)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
file_name = models.CharField(max_length=256)
content_object = GenericForeignKey('content_type', 'object_id')
class Imageable(models.Model):
class Meta:
abstract = True
pictures = GenericRelation(Picture)
class Employee(Imageable):
name = models.CharField(max_length=256)
email = models.EmailField()
class Product(Imageable):
name = models.CharField(max_length=256)
price = models.IntegerField()
동작 확인
# マイグレーション
$ python manage.py makemigrations polymorphic_associations
$ python manage.py migrate polymorphic_associations
$ python manage.py shell
# データ作成
>>> from polymorphic_associations.models import Employee, Product
>>>
>>> employee = Employee(name='John', email='[email protected]')
>>> employee.save()
>>> employee.pictures.create(file_name='employee.jpg')
<Picture: Picture object (1)>
>>>
>>> product = Product(name='Desk', price=1000)
>>> product.save()
>>> product.pictures.create(file_name='product.jpg')
<Picture: Picture object (2)>
# データ取得
>>> employee.pictures.all()
<QuerySet [<Picture: Picture object (1)>]>
>>> employee.pictures.first().file_name
'employee.jpg'
>>>
>>> product.pictures.all()
<QuerySet [<Picture: Picture object (2)>]>
>>> product.pictures.first().file_name
'product.jpg'
# SQL確認
>>> str(employee.pictures.all().query)
'SELECT
"polymorphic_associations_picture"."id",
"polymorphic_associations_picture"."object_id",
"polymorphic_associations_picture"."content_type_id",
"polymorphic_associations_picture"."file_name"
FROM
"polymorphic_associations_picture"
WHERE
(
"polymorphic_associations_picture"."content_type_id" = 2
AND "polymorphic_associations_picture"."object_id" = 1
)'
>>>
>>> str(product.pictures.all().query)
'SELECT
"polymorphic_associations_picture"."id",
"polymorphic_associations_picture"."object_id",
"polymorphic_associations_picture"."content_type_id",
"polymorphic_associations_picture"."file_name"
FROM
"polymorphic_associations_picture"
WHERE
(
"polymorphic_associations_picture"."content_type_id" = 3
AND "polymorphic_associations_picture"."object_id" = 1
)'
작성된 데이터는
content_type_id
, object_id
에 의해 테이블, 레코드를 식별할 수 있음을 알 수 있습니다.이것에 의해 이미지를 가지는 테이블은 모두
Imageable
를 계승하는 것으로 신속하게 구현할 수가 있습니다. 또한 이미지에 대한 처리를 Imageable로 구현함으로써 로직이 각 모델이나 서비스에 분산되는 것을 막을 수 있습니다.이 소스 코드는 Git에 올려져 있습니다.
참고
Reference
이 문제에 관하여(Django Polymorphic Associations Tutorial), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/cohey0727/items/3d7c5e9e1088a1daede6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)