Создание функционала для оформления заказов и покупки — это важнейший элемент любого eCommerce-проекта. В Django это можно реализовать гибко и структурировано, что позволит контролировать весь процесс заказа — от выбора товара до оплаты. В этой статье мы разберем, как с помощью Django создать систему для оформления заказов, включая корзину, обработку заказов и подготовку к оплате.
Структура приложения
Для начала создадим Django-приложение для магазина, которое будет включать следующие основные компоненты:
- Модели товаров и заказов.
- Система корзины для хранения добавленных пользователем товаров.
- Логику для оформления заказа.
- Обработку статуса и подтверждение оплаты.
Для реализации системы оформления заказа и покупки в Django будем работать с тремя основными приложениями:
shop
— для создания каталога товаров и категорий.cart
— для управления корзиной покупок, куда пользователи могут добавлять товары перед оформлением заказа.orders
— для обработки заказов, хранения информации о покупателях и их покупках.
Каждое приложение будет выполнять свои задачи, а вместе они создадут полноценную систему для оформления заказа.
Шаг 1. Создание приложений
Начнем с создания этих приложений. Выполним команды для создания приложений в корневой директории проекта:
python manage.py startapp shop
python manage.py startapp cart
python manage.py startapp orders
Добавим их в INSTALLED_APPS
в settings.py
:
INSTALLED_APPS = [
# другие приложения
'shop',
'cart',
'orders',
]
Шаг 2. Приложение shop
— создание каталога товаров
Приложение shop
будет содержать модели и представления, относящиеся к товарам и их категориям. Оно позволит пользователям просматривать доступные товары и добавлять их в корзину.
Создадим модели товаров и категорий в shop/models.py
:
# shop/models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(unique=True)
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(unique=True)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
available = models.BooleanField(default=True)
stock = models.PositiveIntegerField()
category = models.ForeignKey(Category, related_name='products', on_delete=models.CASCADE)
def __str__(self):
return self.name
Выполним миграции для этих моделей:
python manage.py makemigrations
python manage.py migrate
Шаг 3. Приложение cart
— управление корзиной покупок
Приложение cart
будет обрабатывать корзину, где пользователь может добавлять, удалять и просматривать товары перед оформлением заказа. Корзина будет храниться в сессии, так что товары не исчезнут при обновлении страницы.
Создадим файл cart/cart.py
, в котором определим класс Cart
для управления товарами в корзине:
# cart/cart.py
from decimal import Decimal
from django.conf import settings
from shop.models import Product
class Cart:
def __init__(self, request):
self.session = request.session
cart = self.session.get(settings.CART_SESSION_ID)
if not cart:
cart = self.session[settings.CART_SESSION_ID] = {}
self.cart = cart
def add(self, product, quantity=1, update_quantity=False):
product_id = str(product.id)
if product_id not in self.cart:
self.cart[product_id] = {'quantity': 0, 'price': str(product.price)}
if update_quantity:
self.cart[product_id]['quantity'] = quantity
else:
self.cart[product_id]['quantity'] += quantity
self.save()
def save(self):
self.session.modified = True
def remove(self, product):
product_id = str(product.id)
if product_id in self.cart:
del self.cart[product_id]
self.save()
def __iter__(self):
product_ids = self.cart.keys()
products = Product.objects.filter(id__in=product_ids)
for product in products:
self.cart[str(product.id)]['product'] = product
for item in self.cart.values():
item['price'] = Decimal(item['price'])
item['total_price'] = item['price'] * item['quantity']
yield item
def get_total_price(self):
return sum(Decimal(item['price']) * item['quantity'] for item in self.cart.values())
def clear(self):
del self.session[settings.CART_SESSION_ID]
self.save()
Создадим представления для добавления и удаления товаров из корзины в cart/views.py
:
# cart/views.py
from django.shortcuts import redirect, render, get_object_or_404
from shop.models import Product
from .cart import Cart
def cart_add(request, product_id):
cart = Cart(request)
product = get_object_or_404(Product, id=product_id)
cart.add(product=product, quantity=1, update_quantity=True)
return redirect('cart_detail')
def cart_remove(request, product_id):
cart = Cart(request)
product = get_object_or_404(Product, id=product_id)
cart.remove(product)
return redirect('cart_detail')
def cart_detail(request):
cart = Cart(request)
return render(request, 'cart/detail.html', {'cart': cart})
Шаг 4. Приложение orders
— оформление и обработка заказов
Приложение orders
будет отвечать за создание и обработку заказов, сохранение данных о покупателях и их покупках. Создадим модели для заказов и связанных с ними позиций заказа в orders/models.py
:
# orders/models.py
from django.db import models
from shop.models import Product
class Order(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField()
address = models.CharField(max_length=250)
postal_code = models.CharField(max_length=20)
city = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
paid = models.BooleanField(default=False)
class Meta:
ordering = ('-created',)
def __str__(self):
return f'Order {self.id}'
def get_total_cost(self):
return sum(item.get_cost() for item in self.items.all())
class OrderItem(models.Model):
order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)
product = models.ForeignKey(Product, related_name='order_items', on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
quantity = models.PositiveIntegerField(default=1)
def __str__(self):
return f'{self.quantity} of {self.product.name}'
def get_cost(self):
return self.price * self.quantity
Шаг 5. Создание формы для оформления заказа
Создадим форму для оформления заказа, где пользователи смогут указать свои данные. В orders/forms.py
добавим модельную форму OrderCreateForm
:
# orders/forms.py
from django import forms
from .models import Order
class OrderCreateForm(forms.ModelForm):
class Meta:
model = Order
fields = ['first_name', 'last_name', 'email', 'address', 'postal_code', 'city']
Шаг 6. Представление для оформления заказа
Теперь создадим представление order_create
, которое будет создавать заказ на основе данных корзины. Оно добавит товары из корзины в заказ и сохранит их.
# orders/views.py
from django.shortcuts import render
from .models import OrderItem
from .forms import OrderCreateForm
from cart.cart import Cart
def order_create(request):
cart = Cart(request)
if request.method == 'POST':
form = OrderCreateForm(request.POST)
if form.is_valid():
order = form.save()
for item in cart:
OrderItem.objects.create(order=order, product=item['product'], price=item['price'], quantity=item['quantity'])
cart.clear()
return render(request, 'orders/created.html', {'order': order})
else:
form = OrderCreateForm()
return render(request, 'orders/create.html', {'cart': cart, 'form': form})
Шаг 7. Подтверждение заказа и шаблоны
Создадим шаблоны для оформления и подтверждения заказа. Например, orders/create.html
для ввода данных и orders/created.html
для подтверждения заказа.
<!-- orders/create.html -->
<form method="post">
{{ form.as_p }}
<button type="submit">Оформить заказ</button>
</form>
<!-- orders/created.html -->
<h2>Спасибо за ваш заказ!</h2>
<p>Номер заказа: {{ order.id }}</p>
<p>Мы отправили подтверждение на ваш email.</p>
Теперь ваше приложение включает все три приложения: shop
(каталог товаров), cart
(управление корзиной) и orders
(оформление и обработка заказов). Такая структура позволяет удобно и последовательно реализовать все основные процессы для оформления заказа и покупки.