Urban Store’s product catalog is the public-facing heart of the store. Every product is stored as a MongoDB document managed by MongoEngine, with support for multiple sizes, multiple colors, and fine-grained inventory tracking at the individual size-and-color variant level. The catalog is entirely read-only for shoppers — no authentication is required to browse or filter products — while creation, editing, and deletion are reserved for administrators.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ALEJ4NDRO2025/urban-store/llms.txt
Use this file to discover all available pages before exploring further.
Product Data Model
Each product maps to a document in theproducts MongoDB collection. The fields below come directly from products/models.py:
| Field | MongoEngine Type | Notes |
|---|---|---|
name | StringField(required=True, max_length=200) | Display name of the product |
slug | StringField(required=True, unique=True) | URL-safe identifier, must be unique |
description | StringField() | Long-form product description |
price | DecimalField(required=True, precision=2) | Retail price, 2 decimal places |
category | StringField(required=True) | Product category (e.g. "hoodies") |
stock | IntField(default=0) | General fallback stock count |
sizes | ListField(StringField()) | Available sizes, e.g. ["S", "M", "L", "XL"] |
colors | ListField(StringField()) | Available colors, e.g. ["negro", "blanco", "rojo"] |
stock_by_variant | DictField(default=dict) | Per-variant inventory (see below) |
images | ListField(StringField()) | Cloudinary image URLs |
is_active | BooleanField(default=True) | Soft visibility toggle |
created_at | DateTimeField(default=datetime.utcnow) | Creation timestamp (UTC) |
Per-Variant Inventory
Thestock_by_variant field is a DictField that tracks stock independently for every combination of size and color. The key format is "size|color" — a pipe-separated string. This allows the catalog to report exact availability for each variant without needing a separate collection.
M and color negro, the store checks stock_by_variant["M|negro"] to determine if that variant is in stock. If a variant key is not present in the dict, the backend falls back to the top-level stock field.
A value of
0 means that specific variant is sold out, even if other variants of the same product are available. The frontend should use stock_by_variant to disable out-of-stock size/color combinations in the product selector.Filtering
GET /api/products/ supports four optional query parameters for filtering the active product list:
category
Filter by exact category string.
?category=hoodiesmin_price
Return products priced at or above this value.
?min_price=50000max_price
Return products priced at or below this value.
?max_price=200000size
Return products that include this size in their
sizes list.
?size=Mis_active=True are ever returned regardless of filters.
Cloudinary Image Storage
Product images are not uploaded to or served from Django. Instead, images are uploaded to Cloudinary externally (via the admin panel or a separate upload flow), and the resulting Cloudinary URLs are stored in theimages ListField. The images array may contain multiple URLs for a product gallery.
Admin vs. Public Access
Access control is enforced by the customIsAdminMongo permission class, which decodes the incoming JWT and checks the is_admin flag in the payload — completely independent of DRF’s built-in authentication system.
| Method | Endpoint | Auth Required |
|---|---|---|
GET | /api/products/ | None (public) |
GET | /api/products/<slug>/ | None (public) |
POST | /api/products/ | Admin JWT |
PUT | /api/products/<slug>/ | Admin JWT |
DELETE | /api/products/<slug>/ | Admin JWT |
Example Product Response
GET /api/products/hoodie-urbano-negro/