Django ORM Relationships Cheat Sheet

Written by ent1c3d | Published 2018/12/09
Tech Story Tags: django | orm | cheatsheet | django-orm-relationships | orm-relationships

TLDRvia the TL;DR App

A cheat sheet for Django ORM relationships — version 2.1

I want to start this story with saying thanks to Mahmoud Zalt, who published a really useful article “Eloquent Relationships Cheat Sheet” about a year ago and also gave me permission to use the same structure/images/examples in my article.

  • One to One Relationship
  • One to Many Relationship
  • Many to Many Relationship
  • Polymorphic One to Many Relationship — Generic Relations
  • Polymorphic One to Many Relationship — django-polymorphic package
  • Polymorphic Many to Many Relationship — django-polymorphic package

One to One Relationship

Demo details:

In this demo we have 2 models (Owner and Car), and 2 tables (owners and cars).

Business Rules:

The Owner can own one Car.The Car can be owned by one Owner.

Relations Diagram:

Relationship Details:

The Cars table should store the Owner ID.

Models:

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

Store Records:

car = Car.objects.get(id=1)owner = Owner.objects.get(id=1)

# Create relation between Owner and Car.

owner.car = carowner.car.save()

# Create relation between Car and Owner.

car.owner = ownercar.save()

Retrieve Records:

# Get Owner Car

owner.car

# Get Car Owner

car.owner;

One to Many Relationship

Demo details:

In this demo we have 2 models (Thief and Car), and 2 tables (thieves and cars).

Business Rules:

The Thief can steal many Cars.The Car can be stolen by one Thief.

Relations Diagram:

Relationship Details:

The Cars table should store the Thief ID.

Models:

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

Store Records:

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 = thiefcar.save()

# When we creating new car :car = Car(name = 'test name', thief=thief)car.save()

Retrieve Records:

# Get Thief Car

thief.cars.all()

# Get Car Thief

car.thief

Many to Many Relationship

Demo details:

In this demo we have 2 models (Driver and Car), and 3 tables (drivers, cars and a pivot table named car_drivers).

Business Rules:

The Driver can drive many Cars.The Car can be driven by many Drivers.

Relations Diagram:

Relationship Details:

The Pivot table “car_driver” should store the Driver ID and the Car ID.

Models:

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

Store Records:

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

Retrieve Records:

# Get Driver Car

driver.cars.all()

# Get Car Drivers

car.drivers.all()

Polymorphic One to Many Relationship

With Django’s Generic Relations

Demo details:

In this demo we have 3 models (Man, Woman and Car), and 3 tables (men, women and cars).

Business Rules:

The Man (buyer) can buy many Cars. The Woman (buyer) can buy many Cars.The Car can be bought by one buyer (Man or Woman).

Relations Diagram:

Relationship Details:

The Car table should store the Buyer ID and the Buyer table should store the relation between ID and Type.

Models:

from django.contrib.contenttypes.fields import GenericForeignKeyfrom django.contrib.contenttypes.fields import GenericRelationfrom 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)

Store Records:

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

Retrieve Records:

# Get buyer (Man/Woman) Cars

man.cars.all()woman.cars.all()

# Get Car buyer (Man and Woman)

car.content_object

Polymorphic One to Many Relationship

With package —django-polymorphic.

Demo details:

In this demo we have 4 models (Buyer, Man, Woman and Car), and 4 tables (buyer, men, women and cars).

Business Rules:

The Man (buyer) can buy many Cars. The Woman (buyer) can buy many Cars.The Car can be bought by one buyer (Man or Woman).

Relations Diagram:

Relationship Details:

The Car table should store the Buyer ID and the Buyer table should store the relation between ID and Type.

Models:

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

Store Records:

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

Retrieve Records:

# Get buyer (Man/Woman) Cars

man.cars.all()woman.cars.all()

# Get Car buyer (Man and Woman)

car.buyer

Polymorphic Many to Many Relationship

With package —django-polymorphic.

Demo details:

In this demo we have 3 models (Valet, Owner and Car), and 4 tables (valets, owners, cars and drivers).

Business Rules:

The Valet (driver) can drive many Cars. The Owner (driver) can drive many Cars.The Car can be driven by many drivers (Valet or/and Owner).

Relations Diagram:

Relationship Details:

The Pivot table “drivers” should store the Driver ID, Driver Type and the CarID.“driver” is a name given to a group of models (Valet and Owner). And it’s not limited to two. The driver type is the real name of the model.

Models:

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

Store Records:

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

Retrieve Records:

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

I also highly recommend to read the article, that describes polymorphic many to many relationships with another django package (django-gm2m).

Thanks for reading and stay in touch.


Published by HackerNoon on 2018/12/09