Many-to-One Relationship
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=50)
#Book has a foreignkey (many to one) relationship with author
class Book(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
publish_date = models.DateField()
Most generic option. Can be used anywhere you would like to represent a relationship
Many-to-Many Relationship
class Topping(models.Model):
name = models.CharField(max_length=50)
# One pizza can have many toppings and same topping can be on many pizzas
class Pizza(models.Model):
name = models.CharField(max_length=50)
toppings = models.ManyToManyField(Topping)
Internally this is represented via another table. And ManyToManyField
should be put on models that will be edited on a form. Eg: Appointment
will have a ManyToManyField
called Customer
, Pizza
has Toppings
and so on.
Many-to-Many Relationship using Through classes
class Service(models.Model):
name = models.CharField(max_length=35)
class Client(models.Model):
name = models.CharField(max_length=35)
age = models.IntegerField()
services = models.ManyToManyField(Service, through='Subscription')
class Subscription(models.Model):
client = models.ForeignKey(Client)
service = models.ForeignKey(Service)
subscription_type = models.CharField(max_length=1, choices=SUBSCRIPTION_TYPES)
created_at = models.DateTimeField(default=timezone.now)
This way, we can actually keep more metadata about a relationship between two entities. As can be seen, a client can be subscribed to several services via several subscription types. The only difference in this case is that to add new instances to the M2M relation, one cannot use the shortcut method pizza.toppings.add(topping)
, instead, a new object of the through class should be created, Subscription.objects.create(client=client, service=service, subscription_type='p')
In other languages
through tables
are also known as aJoinColumn
,Intersection table
ormapping table
One-to-One Relationship
class Employee(models.Model):
name = models.CharField(max_length=50)
age = models.IntegerField()
spouse = models.OneToOneField(Spouse)
class Spouse(models.Model):
name = models.CharField(max_length=50)
Use these fields when you will only ever have a composition relationship between the two models.