Django - как добавить многие ко многим с помощью bulk_create?
Вот мои модели:
class MyShop(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='user_profile_shop')
company_name = models.CharField(max_length=150)
shop_commision = models.IntegerField(default=5)
class OrderItem(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)
product = models.ForeignKey(Product, related_name='order_items', on_delete=models.CASCADE)
shop = models.ForeignKey(MyShop, related_name='shop_order', on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
quantity = models.PositiveIntegerField(default=1)
size = models.CharField(max_length=5, null=True, blank=True, )
item_comission = models.IntegerField(default=5)
class ShopInvoice(models.Model):
shop = models.ForeignKey(MyShop, related_name='shop_invoice', on_delete=models.CASCADE)
month = models.DateField()
year = models.DateField()
items = models.ManyToManyField(OrderItem, related_name='items')
total = models.DecimalField(max_digits=10, decimal_places=2)
Вот моя функция: Я использую задание cron и эту функцию для создания объекта для каждого магазина пользователя каждый месяц, но товары не добавляются в объект:
class Command(BaseCommand):
help = 'Generate invoice monthly for shops'
def handle(self, *args, **kwargs):
month_inv = MyShop.objects.all()
for invoice in month_inv:
shop_invoice = invoice.shop_order.all().annotate(year=TruncYear('created'), month=TruncMonth('created')).values(
'month', 'year', 'shop_id'
).annotate(total=Sum(ExpressionWrapper(
(F('item_comission') / 100.00) * (F('price') * F('quantity')), output_field=DecimalField())),
).order_by('month')
ShopInvoice.objects.bulk_create([
ShopInvoice(**kv) for kv in shop_invoice if not ShopInvoice.objects.filter(
shop_id=kv['shop_id'], month=kv['month'], year=kv['year']
).values_list('shop_id', 'month', 'year').exists()
])
class OrderItem(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)
month = models.DateField()
year = models.DateField()
shop_invoice = models.ForeignKey(ShopInvoice, related_name='shop_invoice', on_delete=models.CASCADE)
product = models.ForeignKey(Product, related_name='order_items', on_delete=models.CASCADE)
shop = models.ForeignKey(MyShop, related_name='shop_order', on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
quantity = models.PositiveIntegerField(default=1)
size = models.CharField(max_length=5, null=True, blank=True, )
item_comission = models.IntegerField(default=5)
Я думаю, что вы можете создать для каждого магазина и для каждого месяца счет-фактуру. И оставить "items" и "total" пустыми.
Тогда у вас есть одна таблица со всеми OrderItem (транзакциями), но в ней должно быть поле с "invoice". В views.py вы должны иметь возможность автоматически обновлять это поле, например:
for invoice in OrderItem.objects.all():
invoice = f'{invoice.shop}__{invoice.year}{invoice.month}'
OrderItem.objects.filter(id=invoice.id).update(shop_invoice=invoice)
Следующий результат заключается в том, что вы можете группировать списки транзакций по месяцам и магазинам следующим образом:
for invoice in ShopInvoice.objects.all():
transactions = OrderItem.objects.filter(shop_invoice_id=invoice.id)
Потом там можно суммировать, подсчитывать и прочее и сохранять это в каждой записи ShopInvoice.