Шпаргалка 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
Вернуться на верх