Пример Django Admin Stacked Inline: отношения многие-к-одному и многие-ко-многим

от автора

Как добавить несколько товаров в корзину?

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.
— Попробуем переписать код без использования регулярок и посмотрим, стоит ли тратить время на изучение этой непростой темы.

Регистрируйтесь по ссылке.


ссылка на оригинал статьи https://habr.com/ru/company/otus/blog/690274/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *