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)