Мини-урок-шпаргалка по созданию интернет-магазина на Django. Для разработки нам понадобится готовый html-шаблон.
Функционал и структура магазина:
- Главная страница;
- Страница категорий товаров (страница списка товаров);
- Страница карточки товара;
- Корзина;
- Страница чекаута;
- Модуль приёма платежей;
- Хлебные крошки;
- Страница регистрации и авторизации пользователей;
- Страницы со статическим текстом (например, "Контакты");
- Страница 404
Разработка будет вестись в редакторе Visual Studio Code в ОС Windows 11.
Настройка виртуальной среды
В проводнике Windows создаём папку в которой будем вести разработку интернет-магазина. В моём случае папка будет называться 161-shop.ru. Далее правой кнопкой мыши кликаем по этой папке и выбираем пункт "Показать дополнительные параметры" - "Открыть с помощью Code". Открывается VS Code. Нажимаем Ctrl + ` чтобы открыть консоль.
Для создания виртуального окружения и его запуска последовательно вводим команды:
python -m venv venv
venv\scripts\activate
Установка необходимых для разработки магазина пакетов
Устанавливаем в виртуальное окружение 100% необходимые для разработки магазина пакеты. Вводим команды:
pip install django
pip install django-mptt
pip install pillow
Сразу оговорюсь, что в дальнейшем по мере необходимости мы будем ещё кое-какие пакеты добавлять. Пока же устанавливаем то, что понадобится нам с первых минут разработки.
Создание проекта Django. Первичная настройка
Создадим проект джанго. Сделаем так, чтобы папка основных настроек называлась main. Для этого в командной строке вводим следующую команду (точка в конце команды обязательна и ставится через пробел):
django-admin startproject main .
Создаём в папке 161-shop.ru папку static и в ней две подпапки - assets и uploads. Также в папке 161-shop.ru создаём папку templates. В папке templates у нас будут html-шаблоны нашего магазина. В папке assets статичные файлы этого шаблона, а в папке uploads будут появляться загружаемые нами через админку картинки товаров и тп.
На данный момент структура проекта должна выглядеть вот так:

Однако, в данный момент созданная нами структура папок ещё не работает, т.к сначала нам необходимо сообщить о ней фреймворку Джанго, выполнив первичную настройку.
Первичная настройка Django и первая миграция
Для этого откроем файл main/settings.py и зададим вот такие инструкции:
import os
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
TEMPLATES_DIRS = os.path.join(BASE_DIR, 'templates')
Т.е мы импортировали os, а также занесли в константу TEMPLATES_DIRS информацию о расположении папки templates. Теперь эту константу нужно запихнуть в другую константу - TEMPLATES. А именно внутрь 'DIRS', вот так:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [TEMPLATES_DIRS],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Далее поколдуем с папкой static. Пропишем после STATIC_URL вот такой код:
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
Попутно зададим временную зону и русифицируем админку Джанго:
LANGUAGE_CODE = 'ru-RU'
TIME_ZONE = 'Europe/Moscow'
В список установленных приложений сразу подключим mptt. Для этого добавим в INSTALLED_APPS значение 'mptt', не забыв про запятую в конце.

Проводим первую миграцию. Для этого в консоли последовательно выполняем команды:
python manage.py makemigrations
python manage.py migrate
Создадим суперпользователя:
python manage.py createsuperuser
В учебных целях не заморачиваемся со сложностью пароля.
Стартуем сервер из консоли, чтобы проверить, как всё прошло:
python manage.py runserver
Если всё успешно, то Джанго напишет, что главная страница сайта доступна по адресу http://127.0.0.1:8000/

Проверяем работу админ-панели набрав в адресной строке http://127.0.0.1:8000/admin/ и введя логин и пароль созданного нами ранее суперпользователя. Если всё ок, то вы попадёте в админку.

На этом первичные настройки завершены. Начинаем разрабатывать магазин. Но начнём с обычных страниц.
Создание приложения pages
Выполним команду:
django-admin startapp pages
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('pages.urls', namespace='pages')),
]
from django.urls import path
from . import views
app_name = 'pages' # app name
# pattern for the index page, all products and each product
urlpatterns = [
path('', views.index, name='index'),
]
from django.shortcuts import render, get_object_or_404
# Create your views here.
def index(request):
return render(request, 'index.html')
Создание приложения shop
Создадим основное приложение нашего магазина, которое будет отвечать за товары. Для этого в консоли вводим команду:
django-admin startapp shop
После создания любого приложения в Джанго необходимо его зарегистрировать в main/settings.py. Добавляем в INSTALLED_APPS 'shop.apps.ShopConfig'. Т.е теперь INSTALLED_APPS у нас должен выглядеть вот так:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'mptt',
'shop.apps.ShopConfig',
]
Сразу создадим в появившейся папке shop файл urls.py.
Теперь нам надо изменить файлы следующим образом. В urls.py проекта подключить только что созданный нами файл. Для этого прописываем код:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('shop.urls', namespace='shop')),
]
В файле urls.py, который лежит в папке shop пишем:
from django.urls import path
from . import views
app_name = 'shop' # app name
# pattern for the index page, all products and each product
urlpatterns = [
path('', views.index, name='index'),
]
В файле view.py приложения shop подключаем файл шаблона index.php:
from django.shortcuts import render, get_object_or_404
# Create your views here.
def index(request):
return render(request, 'index.html')
Если всё сделали правильно, то при переходе на главную страницу сайта должна появиться ошибка TemplateDoesNotExist at / index.html

Создание главной страницы сайта
Для начала скопируем из нашего шаблона в папку static/assets все статичные файлы. Далее в папке templates создадим первый файл шаблона - index.html и вставим в него тот код, который у нас в макете от верстальщика. Если мы откроем наш сайт сейчас, но ни увидим никаких картинок тк мы не подключили статику в шаблоне. Начнём редактировать полученный от верстальщика файл index.html. В самом верху этого файла необходим подключить статику (так нужно будет делать для каждого html файла вёрстки).
{% load static %}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
А ссылки типа:
<link rel="stylesheet" href="assets/owlcarousel/owl.carousel.min.css">
<img src="assets/img/products/3.jpg" alt=""></a>
Необходимо преобразовать в:
<link rel="stylesheet" href="{% static 'assets/owlcarousel/owl.carousel.min.css' %}">
<img src="{% static 'assets/img/products/3.jpg' %}"
alt="">
Также сразу стоит выделить в отдельные файлы шапку и подвал сайта. Для этого создайте файлы header.html и footer.html и скопируйте в них части html кода из файла index.html, соответствующие шапке и подвалу сайта. А в файле index.html замените html-код, на код вызова этих частей вот такими конструкциями:
{% load static %}
{% include "header.html" %}
<main class="main">
......
</main>
{% load static %}
{% include "footer.html" %}
При этом помните, что каждый ваш html-файл стоит начинать с конструкции {% load static %}
Создание модели товара
Откройте файл shop/models.py и пропишите следующий код:
from django.db import models
# Create your models here.
class Product(models.Model):
product_name = models.CharField(max_length=200, unique=True, verbose_name='Наименование товара')
product_slug = models.SlugField(max_length=200, unique=True, verbose_name='Постоянная ссылка')
product_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='Цена')
product_quantity = models.IntegerField(verbose_name='Количество на складе')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')
updated_at = models.DateTimeField(auto_now=True, verbose_name='Дата обновления')
def __str__(self):
return self.product_name
class Meta:
verbose_name = 'Товар'
verbose_name_plural = 'Товары'
Вывод информации о товаре views.py:
from django.shortcuts import render, get_object_or_404
from .models import Product
# Create your views here.
def index(request):
return render(request, 'index.html')
def product_detail(request, id):
product = get_object_or_404(Product, pk=id) # get single data
# в product помещаем все данные о текущем товаре. в дальнейшем в шаблоне будем вызывать так: product.title
# где title - название одного из полей товара из созданной нами модели в models.py
context = {
'product' : product,
}
return render(request, 'single-product.html', context)
urls.py
from django.urls import path
from . import views
app_name = 'shop' # app name
# pattern for the index page, all products and each product
urlpatterns = [
path('', views.index, name='index'),
path('product/<int:id>/', views.product_detail, name='product_detail'),
]
single-product.html
<h1 class="section-title h3"><span>{{ product.product_name }}</span></h1>
<div class="product-price">
{% if product.product_sale_price > 0 %}
<small>{{ product.price }} ₽</small>
{{ product.product_sale_price }} ₽
{% else %}
{{ product.product_price }} ₽
{% endif %}
</div>
<p>{{ product.product_description }}</p>