Как вычесть содержимое IntegerField одной таблицы из другой в Django?
Как это работает: Когда я добавляю товар в таблицу Bouquet, в классе CompositionOfTheBouquetInline я могу выбрать объект из таблицы Flower и выбрать количество цветов.
Например,
- в таблице Flower находится цветок "Роза", stock = 10 .
- в таблице Bouquet есть букет "Букет роз", stock = 1
- выберите цветок "Роза" в количестве 5 штук и сохраните, в таблице CompositionOfTheBouquet
Что произойдет:
- цветок "Роза" теперь сток = 5, в таблице Цветок
Формула:
- Flower.stock = Flower.stock - (CompositionOfTheBouquet.count * Bouquet.stock)
models.py
class Flower(models.Model):
title = models.CharField(max_length=100)
stock = models.PositiveIntegerField(default=0)
class Bouquet(models.Model):
title = models.CharField(max_length=150)
stock = models.PositiveIntegerField(default=0)
class CompositionOfTheBouquet(models.Model):
flower = models.ForeignKey(
Flower, on_delete=models.PROTECT
)
bouquet = models.ForeignKey(
Bouquet, on_delete=models.PROTECT
)
count = models.PositiveIntegerField(default=0)
admin.py
from .models import Flower, Bouquet, CompositionOfTheBouquet
class CompositionOfTheBouquetInline(admin.TabularInline):
model = CompositionOfTheBouquet
@admin.register(Flower)
class Flower(admin.ModelAdmin):
pass
@admin.register(Bouquet)
class Bouquet(admin.ModelAdmin):
inlines = [CompositionOfTheBouquetInline, ]
Что нужно сделать: При добавлении цветка и его количества, нужно удалить это количество цветов и сохранить его в таблице Flower, столбец stock.
Важно: расчеты должны производиться при добавлении букета через панель администратора
Мое предложение - переопределить поведение сохранения модели CompositionOfTheBouquet
.
Если это не должно быть поведением по умолчанию при каждом создании/обновлении CompositionOfTheBouquet
модели, рассмотрите возможность использования proxy models для переопределения метода save()
только на proxy классе.
Этого также можно достичь с помощью сигналов, но, согласно этому антипаттерну, лучше их избегать.
Примечание: предполагая count
свойство - количество цветов в одном букете.
class CompositionOfTheBouquet(models.Model):
flower = models.ForeignKey(
Flower, on_delete=models.PROTECT
)
bouquet = models.ForeignKey(
Bouquet, on_delete=models.PROTECT
)
count = models.PositiveIntegerField(default=0)
# Override __init__ method to keep track of what changed (saves a trip to DB)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._initial_count = self.count
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
# After saving the `CompositionOfTheBouqet` model, update the `Flower`
# model using the formula you provided with a small change. Using the
# count_diff to update the number of flower only by the changed count.
# This is needed for update scenarios. Also, when you reduce number
# of flowers in the composition, the flower stock will increase
count_diff = self.count - self._initial_count
if count_dict != 0: # Only update the flower if count has changed
self.flower.stock = self.flower.stock - (count_diff * self.bouquet.stock)
self.flower.save()
PS. - небольшое замечание по поводу логики. Если вы выберете слишком много цветов, вы получите ошибку базы данных при установке отрицательного числа в PositiveIntegerField
. Это должно быть обработано некоторой валидацией, я полагаю.