[PYTHON] Django Polymorphic Associations Tutorial

Einführung

Mein Artikel Django verhält sich anders als andere polymorphe Ich schrieb über die Tatsache, dass sich das polymorphe Modell von Django von dem sogenannten polymorphen Modell unterscheidet. Dieses Mal werde ich den Punkt "Wie man ** polymorphe verwandte ** in Django implementiert" erklären.

Umgebung

Tor

Im Kapitel [Polymorphe Assoziationen] des Rails-Handbuchs (https://guides.rubyonrails.org/association_basics.html#polymorphic-associations) wird die polymorphe Beziehung wie folgt implementiert.

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

Ziel ist es, ein Modell mit den folgenden ER-ähnlichen Attributen zu implementieren.

imageable.png

coontent_type gibt an, welche Tabelle zugeordnet ist, und object_id gibt an, welcher Datensatz zugeordnet ist.

Implementierung

Modellieren

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()

Implementierung der Imageable-Klasse

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()

Funktionsprüfung

#Migration
$ python manage.py makemigrations polymorphic_associations
$ python manage.py migrate polymorphic_associations
$ python manage.py shell


#Datenerstellung
>>> 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)>


#Datenerfassung
>>> 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-Bestätigung
>>> 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
    )'

Sie können sehen, dass die erstellten Daten die Tabelle und den Datensatz anhand von "content_type_id" und "object_id" identifizieren können. Dadurch können alle Tabellen mit Bildern schnell implementiert werden, indem "Imageable" geerbt wird. Sie können auch verhindern, dass die Logik auf Modelle und Dienste verteilt wird, indem Sie die bildbezogene Verarbeitung in Imageable implementieren. Dieser Quellcode befindet sich in Git.

Referenz

Recommended Posts

Django Polymorphic Associations Tutorial
Python Django Tutorial (5)
Python Django Tutorial (2)
Django Tutorial Memo
Python Django Tutorial (8)
Python Django Tutorial (6)
Starten Sie das Django Tutorial 1
Python Django Tutorial (7)
Python Django Tutorial (1)
Python Django Tutorial Tutorial
Python Django Tutorial (3)
Python Django Tutorial (4)
Zusammenfassung des Python Django-Tutorials
Django Oscar einfaches Tutorial
Django Girls Tutorial Hinweis
Fangen Sie mit Django an! ~ Tutorial ⑤ ~
Fangen Sie mit Django an! ~ Tutorial ④ ~
Fangen Sie mit Django an! ~ Tutorial ⑥ ~
Python Django Tutorial Cheet Sheet
Django
Django Girls Tutorial Zusammenfassung Erste Hälfte
Stolpern Sie beim Django 1.7-Tutorial
Stellen Sie das Django-Lernprogramm für IIS bereit ①
Django Crispy Tutorial (Umgebungskonstruktion auf Mac)
Django Tutorial Zusammenfassung für Anfänger von Anfängern ③ (Anzeigen)
Django Tutorial (Blog-App erstellen) ⑤ - Artikelerstellungsfunktion
Djangos External Key Tutorial in 10 Minuten
Django Tutorial (Blog App erstellen) ④ --Einheitentest
Django Tutorial Zusammenfassung für Anfänger von Anfängern ⑤ (Test)