01 Aug 2023
Django ORM maps attributes to columns in the database.
Ecommerce website that sells books. You need the following models: Book, Cart. This approach is non-polymorphic.
class Book(Model):
name = models.CharField(
max_length=100,
)
price = models.PositiveIntegerField(
help_text='in cents',
)
weight = models.PositiveIntegerField(
help_text='in grams',
)
class Cart(Model):
user = models.OneToOneField(
get_user_model(),
primary_key=True,
on_delete=models.CASCADE,
)
books = models.ManyToManyField(Book)
To create a cart with books:
book = Book.objects.create(name="Awesome book", price=100, weight=200)
user = get_user_model().create_user("Some user")
cart = Cart.objects.create(user=user)
cart.products.add(book)
Abstract base model creates an abstract base class that only exists in the code, not in the database.
class Product(Model):
class Meta:
abstract = True
name = models.CharField(
max_length=100,
)
price = models.PositiveIntegerField(
help_text='in cents',
)
class Book(Product):
weight = models.PositiveIntegerField()
class EBook(Product):
download_link = models.URLField()
Both Book and EBook inherit from Product. Now let’s create the Cart.
class Cart(Model):
user = models.OneToOneField(
get_user_model(),
primary_key=True,
on_delete=models.CASCADE,
)
# we have to create a different variable for each type of product
book = models.ManyToManyField(Book)
ebooks = models.ManyToManyField(EBook)
Concrete base model is an approach that does create a separate table in the database.
In this example we have both Books and EBooks in our store. Note that the Product Model is not defined with abstract = True.
class Product(Model):
name = models.CharField(
max_length=100,
)
price = models.PositiveIntegerField(
help_text='in cents',
)
class Book(Product):
weight = models.PositiveIntegerField()
class EBook(Product):
download_link = models.URLField()
Create new products:
book = Book.objects.create(...)
ebook = EBook.objects.create(...)
This will add an entry in the Product table that will contain all the common fields, and 2 entries in the book and ebook tables, for the values specific to their respective products.
Notice the productptrid in Books table which points to its respective item in Products table.
| Column | Type |
|---|---|
| productptrid | integer |
| weight | integer |
Django performs a join in the background when fetching a book.
Since all products are managed in the Product table, you can reference them using a foreign key in the Cart model.
class Cart(Model):
...
items = models.ManyToManyField(Product)
cart = Cart.objects.create(user=user)
cart.items.add(book, ebook)