To start, make sure that django.contrib.admin is in INSTALLED_APPS in the settings, and hook up the admin site in the URL configuration, as follows:
# project/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
# ...
]
Next, create a new products app, and put it under INSTALLED_APPS, adding the volume to the Docker Compose configuration if needed. This app will have the Product and ProductPhoto models, where one product might have multiple photos. For this example, we will also be using UrlMixin, which was defined in the Creating a model mixin with URL-related methods recipe, in Chapter 2, Database Structure and Modeling.
Let's create the Product and ProductPhoto models in the models.py file, as follows:
# products/models.py import os
from django.urls import reverse, NoReverseMatch
from django.db import models
from django.utils.timezone import now as timezone_now
from django.utils.translation import ugettext_lazy as _
from utils.models import UrlMixin
def product_photo_upload_to(instance, filename):
now = timezone_now()
slug = instance.product.slug
base, ext = os.path.splitext(filename)
return f"products/{slug}/{now:%Y%m%d%H%M%S}{ext.lower()}"
class Product(UrlMixin):
class Meta:
verbose_name = _("Product")
verbose_name_plural = _("Products")
title = models.CharField(_("title"),
max_length=200)
slug = models.SlugField(_("slug"),
max_length=200)
description = models.TextField(_("description"),
blank=True)
price = models.DecimalField(_("price (€)"),
max_digits=8,
decimal_places=2,
blank=True,
null=True)
def get_url_path(self):
try:
return reverse("product_detail",
kwargs={"slug": self.slug})
except NoReverseMatch:
return ""
def __str__(self):
return self.title
class ProductPhoto(models.Model):
class Meta:
verbose_name = _("Photo")
verbose_name_plural = _("Photos")
product = models.ForeignKey(Product,
on_delete=models.CASCADE)
photo = models.ImageField(_("photo"),
upload_to=product_photo_upload_to)
def __str__(self):
return self.photo.name
Don't forget to make and run an initial migration for the new products app, once your models are in place.