Шпаргалка Django ORM Relationships

Отношения один на один

Детали демонстрации:

В этой демонстрации у нас есть 2 модели (Owner и Car) и 2 таблицы (владельцы и автомобили).

Правила:

  • Владелец может владеть одним Автомобилем.
  • Автомобиль может принадлежать одному Владельцу.

Диаграмма связей:

Детали отношений:

В таблице Cars должен храниться идентификатор владельца (Owner ID).

Модели:

class Owner(models.Model):

    #...
    name = models.CharField(max_length=255)
class Car(models.Model):

    #...
    name = models.CharField(max_length=255)
    owner = models.OneToOneField(
        Owner,
        on_delete=models.CASCADE,
        related_name='car'
    )

Записи в магазине:

car = Car.objects.get(id=1)
owner  = Owner.objects.get(id=1)
# Create relation between Owner and Car.
owner.car = car
owner.car.save()
# Create relation between Car and Owner.
car.owner = owner
car.save()

Получение записей:

# Get Owner Car
owner.car

# Get Car Owner
car.owner;

Отношения "один ко многим"

Детали демонстрации:

В этой демонстрации у нас есть 2 модели (Thief и Car) и 2 таблицы (воры и автомобили).

Правила:

  • Вор может украсть много машин.
  • Автомобиль может быть украден одним Вором.

Диаграмма связей:

Детали отношений:

В таблице Cars должен храниться Thief ID.

Модели:

class Thief(models.Model):

    # ...
    name = models.CharField(max_length=255)

class Car(models.Model):

    # ...
    name = models.CharField(max_length=255)
    thief = models.ForeignKey(
        Thief,
        on_delete=models.CASCADE,
        related_name='cars'
    )

Записи в магазине:

thief  = Thief.objects.get(id=1)
car1 = Car.objects.get(id=1)
...
# Create relation between Thief and Car.
thief.cars.add(car1,car2, car3)
# Create relation between Car and Thief.
car.thief = thief
car.save()
# When we creating new car : 
car = Car(name = 'test name', thief=thief)
car.save()

Получение записей:

# Get Thief Car  
thief.cars.all()
# Get Car Thief
car.thief

Отношения "многие ко многим"

Детали демонстрации:

В этой демонстрации у нас есть 2 модели (Driver и Car) и 3 таблицы (драйверы, автомобили и сводная таблица с именем car_drivers).

Правила:

  • Водитель может водить много автомобилей.
  • Автомобилем могут управлять многие водители.

Диаграмма связей:

Детали отношений:

В сводной таблице car_driver должны храниться идентификаторы водителя Driver ID и автомобиля Car ID.

Модели:

class Driver(models.Model):

    # ...
    name = models.CharField(max_length=255)
class Car(models.Model):

    # ...
    name = models.CharField(max_length=255)
    drivers = models.ManyToManyField(
        Driver,
        related_name='cars'
    )

Записи в магазине:

# Create relation between Driver and Car.
driver  = Driver.objects.get(id=1)
car1 = Car.objects.get(id=1)
car2 = Car.objects.get(id=2)
driver.cars.add(car1,car2)
# Create relation between Car and Driver.
car = Car.objects.get(id=1)
driver1  = Driver.objects.get(id=2)
driver2  = Driver.objects.get(id=3)

car.drivers.add(driver1, driver2)

Получение записей:

# Get Driver Car
driver.cars.all()
# Get Car Drivers
car.drivers.all()

Полиморфные отношения "один ко многим"

С общими отношениями (Generic Relations) Django

Детали демонстрации:

В этой демонстрации у нас есть 3 модели (Man, Woman и Car) и 3 таблицы (мужчины, женщины и автомобили).

Правила:

  • Мужчина (покупатель) может купить много Автомобилей.
  • Женщина (покупатель) может купить много Автомобилей.
  • Машину может купить один покупатель (мужчина или женщина).

Диаграмма связей:

Детали отношений:

В таблице Car должен храниться идентификатор покупателя, а в таблице покупателя должна храниться связь между идентификатором ID и типом Type.

Модели:

from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.fields import GenericRelation
from django.contrib.contenttypes.models import ContentType
class Car(models.Model):
    # ...
    name = models.CharField(max_length=255)
    content_type = models.ForeignKey(ContentType,         on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey()
class Woman(models.Model):
    # ...
    name = models.CharField(max_length=255)
    cars = GenericRelation(Car)
class Man(models.Model):
    # ...
    name = models.CharField(max_length=255)
    cars = GenericRelation(Car)

Записи в магазине:

man = Man.objects.get(id=1)
woman = Woman.objects.get(id=1)
# Create relation between buyer (Man/Woman) and Car.
car = Car.objects.get(id=1)
woman.cars.add(car)
# Create relation between Car and buyer (Men/Women).
man = Man.objects.get(id=1)
woman = Woman.objects.get(id=1)
c = Car(name = 'test name',content_object=man)
c.save()
c = Car(name = 'test name',content_object=woman)
c.save()

Получение записей:

# Get buyer (Man/Woman) Cars
man.cars.all()
woman.cars.all()
# Get Car buyer (Man and Woman)
car.content_object

Полиморфные отношения "один ко многим"

С пакетом — django-polymorphic.

Детали демонстрации:

В этой демонстрации у нас есть 4 модели (Buyer, Man, Woman и Car) и 4 таблицы (покупатель, мужчины, женщины и автомобили).

Правила ведения бизнеса:

  • Мужчина (покупатель) может купить много Автомобилей.
  • Женщина (покупатель) может купить много Автомобилей.
  • Машину может купить один покупатель (мужчина или женщина).

Диаграмма связей:

Детали отношений:

В таблице Car должен храниться идентификатор покупателя, а в таблице покупателя должна храниться связь между идентификатором и типом.

Модели:

from polymorphic.models import PolymorphicModel
class Buyer(PolymorphicModel):
    pass

class Woman(Buyer):

    # ...
    name = models.CharField(max_length=255)



class Man(Buyer):

    # ...
    name = models.CharField(max_length=255)



class Car(models.Model):

    # Fields

    name = models.CharField(max_length=255)
    buyer = models.ForeignKey(
        Buyer,
        on_delete=models.CASCADE,
        related_name='cars'
    )

Записи в магазине:

man = Buyer.objects.get(id=1) # or Man.objecets.get(id=1)
woman = Buyer.objects.get(id=2) # or Woman.objecets.get(id=2)
# Create relation between buyer (Man/Woman) and Car.
man.cars.add(car1, car2)
woman.cars.add(car1, car2)
# Create relation between Car and buyer (Men/Women).
c = Car(name = 'test name', buyer = man)
c.save()
c = Car(name = 'test name', buyer = woman)
c.save()

Получение записей:

# Get buyer (Man/Woman) Cars
man.cars.all()
woman.cars.all()
# Get Car buyer (Man and Woman)
car.buyer

Полиморфные отношения "многие ко многим"

С пакетом — django-polymorphic.

Детали демонстрации:

В этой демонстрации у нас есть 3 модели (Valet, Owner и Car) и 4 таблицы (камердинеры, владельцы, автомобили и водители).

Правила ведения бизнеса:

  • Камердинер (водитель) может водить много автомобилей.
  • Владелец (водитель) может водить много Автомобилей.
  • Автомобилем могут управлять многие водители (камердинер и/или владелец).

Диаграмма связей:

Детали отношений:

В сводной таблице «drivers» должны храниться идентификатор драйвера, тип драйвера и CarID. «Водитель» - это название, данное группе моделей (Valet и Owner). И это не ограничивается двумя. Тип драйвера - это настоящее название модели.

Модели:

from polymorphic.models import PolymorphicModel
class Driver(PolymorphicModel):
    pass
class Owner(Driver):

    # ...
    name = models.CharField(max_length=255)


class Valet(Driver):

    # ...
    name = models.CharField(max_length=255)



class Car(models.Model):

    # ...

    name = models.CharField(max_length=255)
    drivers = models.ManyToManyField(
        Driver,
        related_name='cars'
    )

Записи в магазине:

# Create relation between driver (Valet/Owner) and Car.
owner.cars.add(car1, car2)
# Create relation between Car and driver (Valet/Owner).
car.drivers.add(owner, valet)

Получение записей:

# Get driver (Valet/Owner) Cars
valet.cars.all()
owner.cars.all()
# Get Car drivers (Valet and Owner)
car.drivers.all()
car1.drivers.instance_of(Valet)
car1.drivers.instance_of(Owner)

Я также очень рекомендую прочитать статью, в которой описываются полиморфные отношения "многие ко многим" с помощью другого пакета django (django-gm2m).

https://hackernoon.com/django-orm-relationships-cheat-sheet-14433d6cf68c

Вернуться на верх