Как добавить несколько товаров в корзину?
Django Admin — довольно мощный инструмент при работе с данными в стиле CRUD (создание, чтение, модификация, удаление). Одна из особенностей, о которой многие (даже опытные) разработчики не подозревают, — это наличие нескольких строк «many-one» или «many-to-many» на одной странице, как показано на этом рисунке:

Потрясно, правда? А рецепт простой, давайте посмотрим.
Data (Models)
from django.db import models class Item(models.Model): name = models.CharField(max_length=100) price = models.DecimalField(default=0, decimal_places=2, max_digits=10) def __str__(self): return f"{self.name}: ${self.price}" class Cart(models.Model): created = models.DateTimeField(auto_now_add=True) paid = models.BooleanField(default=False) def total_price(self): return sum([ cart_item.total() for cart_item in CartItem.objects.filter(cart=self) ]) def __str__(self): return f"{self.created}, ${self.total_price()}: {self.paid}" class CartItem(models.Model): cart = models.ForeignKey(Cart, on_delete=models.CASCADE) item = models.ForeignKey(Item, on_delete=models.CASCADE) count = models.IntegerField(default=1) def total(self): return self.count * self.item.price def __str__(self): return f"{self.item.name}, " \ f"${self.item.price} * {self.count} = ${self.total()}"
Модели просты: у нас есть Items, Carts и таблица CartItem для отношения многие-ко-многим между Items и Carts. Мы не могли использовать здесь models.ManyToManyField, так как нам нужно дополнительное поле “count” внутри отношений. Когда я сам создаю отношения, это кажется более прозрачным.
Admin
Внутри Admin мы не просто регистрируем модели напрямую, нам нужно создать классы ModelAdmin и StackedInline.
Идея заключается в следующем. Сначала мы создаем многострочное представление (multiline view) для поддержки CRUD в таблице CartItem. А затем мы добавляем это представление к представлению корзины.
Это делается следующим образом:
from django.contrib import admin from shop.models import Cart, Item, CartItem class ItemInline(admin.StackedInline): model = CartItem extra = 5 class CartAdmin(admin.ModelAdmin): inlines = [ItemInline] list_display = ["created", "total_price", "paid"] admin.site.register(Cart, CartAdmin) admin.site.register(Item)
Вот и все. Полезная вещь и не занимает много времени.
Скоро состоится открытое занятие «О "регулярках" и не только», на котором:
- Поговорим о роли регулярных выражений в разработке.
- Оценим эффект от re.compile.
- Попробуем переписать код без использования регулярок и посмотрим, стоит ли тратить время на изучение этой непростой темы.Регистрируйтесь по ссылке.
