Дикий Григорий

Full-stack веб-разработчик

Интернет-магазин на Django. Система купонов. Часть 12

Сегодня мы продолжим работать над нашей системой купонов. В прошлый раз мы добились того, что купон включался в корзине пользователя, теперь нам нужно, чтобы они также были и при самом заказе, для этого в директории orders изменим шаблон order/create.html:

<ul>
      {% for item in cart  %}
        <li>
          {{ item.product.name }} | Количество: {{ item.quantity }} | Цена: {{ item.total_price }}
        </li>
      {% endfor %}
      {% if cart.cupon %}
        <li>
          "{{ cart.cupon.code }}" (на {{ cart.cupon.discount }}% меньше)
          <span> - {{ cart.get_discount|floatformat:"2"}} руб.</span>
        </li>
      {% endif %}
    </ul>
    <p><strong>Всего:</strong> {{ cart.get_total_price_after_discount|floatformat:"2"}} руб.</p>

В итоге перейдя по адресу http://127.0.0.1:8000/order/create/ мы увидим, что наши изменения применились:

Нам нужно, чтобы при заказе товаров пользователь платил с учетом купона. Пока что у нас не реализован такой функционал. Для этого нам нужно изменить models.py в директории orders:

...
from cupons.models import Cupon
from decimal import Decimal
from django.core.validators import MinValueValidator, MaxValueValidator


class Order(models.Model):
    ...
    cupon = models.ForeignKey(Cupon, related_name='orders', null=True, blank=True)
    discount = models.IntegerField(default=0, validators=[MinValueValidator(0),
                                                          MaxValueValidator(100)]

Это позволит применять купоны к товарам и устанавливать скидку для них. Так как мы изменили модель Oreders, нам нужно синхронизироваться с базой данных:

$ python manage.py makemigrations
$ python manage.py migrate

Теперь нам нужно изменить стоимость товара с учетом скидки, для этого нужно изменить функцию get_total_cost() в классе Order:

def get_total_cost(self):
    total_cost = sum(item.get_cost() for item in self.items.all())
    return total_cost - total_cost * (self.discount / Decimal('100'))

Теперь нам нужно изменить обработку формы во вьюхе OrderCreate, для этого откройте файл views.py и измените следующее:

if form.is_valid():
    order = form.save(commit=False)
    if cart.cupon:
        order.cupon = cart.cupon
        order.discount = cart.cupon.discount

Мы не сохраняем форму в БД иcпользуя commit=False. Если корзина содержит купон, то мы применяем его. Давайте запустим наш сайт и активируем ngrok:

$ python manage.py runserver
$ ./ngrok http 8000

Теперь можно купить товары и проверить работоспособность нашей системы купонов. После проверки можно зайти в админ-панель, перейти во вкладку заказы и выбрать последний заказ:

Как видите нам показано, если применялись купоны и также показана скидка. С системой купонов все. Осталось настроить систему интернационализации и наш онлайн-магазин готов к использованию.

Репозиторий проекта: github