Build REST API for E-commerce App0%
Build REST API for E-commerce App
Beginner12 min read•Updated: Jul 11, 2026
DRF Capstone: E-Commerce API Data Model and Architecture
In this capstone series, we design and build a production-grade, multi-model E-Commerce REST API. We begin by architecting the relational database schema, model relationships, managers, and data flow.
1. System Architecture & Entity Relationships
An enterprise E-Commerce API requires strict relational integrity across products, categories, shopping carts, orders, and user profiles:
Output
[ User ] (Django Auth)
│
├── (1:1) ── [ CustomerProfile ] (phone, address)
│
├── (1:N) ── [ Order ] (status, created_at, total)
│ │
│ └── (1:N) ── [ OrderItem ] (product, unit_price, quantity)
│ │
└── (1:1) ── [ Cart ] │
│ ▼
└── (1:N) ── [ CartItem ] ── (N:1) ── [ Product ] ── (N:1) ── [ Category ]
2. Model Definitions: Products & Categories
In store/models.py:
Python
import uuid
from django.db import models
from django.conf import settings
from django.core.validators import MinValueValidator
class Category(models.Model):
name = models.CharField(max_length=100, unique=True)
slug = models.SlugField(max_length=120, unique=True)
description = models.TextField(blank=True)
class Meta:
verbose_name_plural = 'Categories'
ordering = ['name']
def __str__(self):
return self.name
class Product(models.Model):
category = models.ForeignKey(Category, on_delete=models.PROTECT, related_name='products')
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=220, unique=True)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2, validators=[MinValueValidator(0.01)])
inventory = models.PositiveIntegerField()
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-created_at']
def __str__(self):
return self.title
3. Carts, Orders, and Items
Python
class Cart(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.id)
class CartItem(models.Model):
cart = models.ForeignKey(Cart, on_delete=models.CASCADE, related_name='items')
product = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.PositiveSmallIntegerField(validators=[MinValueValidator(1)])
class Meta:
unique_together = [['cart', 'product']]
class Order(models.Model):
STATUS_PENDING = 'P'
STATUS_COMPLETE = 'C'
STATUS_FAILED = 'F'
STATUS_CHOICES = [
(STATUS_PENDING, 'Pending'),
(STATUS_COMPLETE, 'Complete'),
(STATUS_FAILED, 'Failed'),
]
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
customer = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, related_name='orders')
placed_at = models.DateTimeField(auto_now_add=True)
payment_status = models.CharField(max_length=1, choices=STATUS_CHOICES, default=STATUS_PENDING)
shipping_address = models.CharField(max_length=255)
class Meta:
ordering = ['-placed_at']
class OrderItem(models.Model):
order = models.ForeignKey(Order, on_delete=models.PROTECT, related_name='items')
product = models.ForeignKey(Product, on_delete=models.PROTECT)
unit_price = models.DecimalField(max_digits=10, decimal_places=2)
quantity = models.PositiveSmallIntegerField()
Interactive Quiz
Practice Quiz
Question 1
Why is
on_delete=models.PROTECT used for category on the Product model instead of CASCADE?Question 2
Why is a UUID primary key preferable to an auto-incrementing integer ID for
Cart and Order models?Question 3
Why does
OrderItem store a separate unit_price field instead of referencing product.price dynamically?Question 4
What constraint does
unique_together = [['cart', 'product']] enforce on CartItem?Question 5
What does
MinValueValidator(1) enforce on CartItem.quantity?Next Lesson
CRUD, Authentication, Filtering, Pagination
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Related Lessons
| Previous Lesson | Next Lesson |
|---|---|
| Documenting API Endpoints | CRUD, Authentication, Filtering, Pagination |
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.