Engineering Journal11 May 2026
Django DRF - Part 01 - ECommerce Model Architecture
FB
Bhuvan
Technical Staff
11Total Views
5mRead Time

Before diving into code, it is essential to visualize how these entities interact. In a standard E-commerce flow:
- A User places an Order.
- An Order can contain multiple Products.
- An OrderItem acts as the "link," tracking exactly how many of a specific product were bought in a specific order.
graph TD
%%{init: {'theme': 'dark', 'themeVariables': {
'primaryColor': '#f8f8f8',
'primaryTextColor': '#f3f4f6',
'lineColor': '#9ca3af',
'tertiaryColor': '#3f60a5'
}}}%%
User[User Model] -->|Places| Order[Order Model]
Order -->|Contains Many| OrderItem[OrderItem Model]
Product[Product Model] -->|Linked to| OrderItem
classDef user fill:#4b5563,stroke:#9ca3af,stroke-width:2px,color:#f3f4f6;
classDef netlify fill:#0e7490,stroke:#22d3ee,stroke-width:2px,color:#f3f4f6;
classDef aws fill:#9a3412,stroke:#fb923c,stroke-width:2px,color:#f3f4f6;
classDef db fill:#065f46,stroke:#34d399,stroke-width:2px,color:#f3f4f6;
class User user;
class Order netlify;
class Product aws;
class OrderItem db;
Implementation Code
python
# 1. Product Catalog
class Product(models.Model):
name = models.CharField(max_length=200)
description = models.TextField()
# DecimalField is critical for financial accuracy
price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.PositiveIntegerField()
image = models.ImageField(upload_to='products/', blank=True, null=True)
@property
def in_stock(self):
return self.stock > 0
def __str__(self):
return self.name
# 2. Order Management
class Order(models.Model):
class StatusChoices(models.TextChoices):
PENDING = 'Pending'
CONFIRMED = 'Confirmed'
CANCELLED = 'Cancelled'
# UUID prevents predictable Order IDs
order_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='orders')
created_at = models.DateTimeField(auto_now_add=True)
status = models.CharField(
max_length=10,
choices=StatusChoices.choices,
default=StatusChoices.PENDING
)
# Linking products via the OrderItem helper table
products = models.ManyToManyField(Product, through="OrderItem", related_name='orders')
def __str__(self):
return f"Order {self.order_id} by {self.user.username}"
# 3. Transaction Details (The 'Through' Table)
class OrderItem(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField()
@property
def item_subtotal(self):
return self.product.price * self.quantity
def __str__(self):
return f"{self.quantity} x {self.product.name} (Order: {self.order.order_id})"Model-by-Model Breakdown
A. The User Model
Even if you don't need custom fields immediately, inheriting from AbstractUser is a professional best practice. It allows you to add fields (like phone numbers or addresses) later without breaking your database schema.
B. The Product Model
This model stores the "catalog" details.
DecimalField: Used for price. Never useFloatFieldfor money because floats can lead to rounding errors in calculations.DecimalFieldensures fixed-point precision (e.g., 10.99).PositiveIntegerField: Ensures stock levels never accidentally become negative numbers.@property(in_stock): A "calculated" field. It doesn't live in the database but provides a quick boolean check to see if customers can buy the item.
C. The Order Model
The Order model tracks the transaction lifecycle.
UUIDField: Instead of a standard ID (1, 2, 3...), we use a UUID. This is more secure because it prevents users from guessing order numbers or seeing how many total orders your store has processed.StatusChoices: A clean way to limit the "status" to specific options like Pending or Cancelled, preventing data entry errors.ManyToManyField: An order has many products, and a product can be in many orders. We usethrough="OrderItem"to tell Django we want to store extra data (like quantity) on that link.
D. The OrderItem Model
This is the "Join Table." While the Order knows who bought things, the OrderItem knows exactly how much of what they bought.
ForeignKey: Links the item specifically to one Order and one Product.item_subtotal: A logic helper that calculatesprice * quantityfor that specific line item.
Distribute Knowledge
Further Reading
Filter B
11 May
5 Min Read
Django DRF - Part 02 - Serializers & Views
Technical deep dive into modern architecture and development strategies.
Read Article

25 Apr
5 Min Read
🚀 5 Python Concepts You Must Master Before Your First Line of Django
Technical deep dive into modern architecture and development strategies.
Read Article