Django-polymorphic Сумма агрегатов Цена
Мне нужен чистый способ суммировать цену всех продуктов в наборе запросов при использовании django-polymorphic.
Установите зависимости:
pip install django-polymorphic
Создайте приложение:
manage.py startapp content
путь: content/models.py
from django.db import models
from polymorphic.models import PolymorphicModel
from polymorphic.managers import PolymorphicManager
from django.utils.text import slugify
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
class Content(PolymorphicModel):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='content')
title = models.CharField(max_length=100)
slug = models.SlugField(max_length=100)
objects = PolymorphicManager()
class Meta:
unique_together = ('user', 'slug')
def __str__(self):
return str(self.title)
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super().save(*args, **kwargs)
class Post(Content):
pass
class Note(Content):
pass
class ProductA(Content):
price = models.DecimalField(max_digits=6, decimal_places=2, null=True)
class ProductB(Content):
price = models.DecimalField(max_digits=6, decimal_places=2, null=True)
путь: project/settings.py
INSTALLED_APPS = [
...
'content.apps.ContentConfig' # add this
]
AUTH_USER_MODEL = 'content.user'
Выполнено:
manage.py makemigrations
manage.py migrate
В интерактивной оболочке:
u, _ = User.objects.get_or_create(username='user')
post = Post.objects.create(user=u, title='First Post')
note = Note.objects.create(user=u, title='First Note')
prod_a = ProductA.objects.create(user=u, title='First Product A', price=12.99)
prod_b = ProductB.objects.create(user=u, title='First Product B', price=18.99)
Мне нужен чистый способ суммирования цен всех продуктов в наборе запросов.
Пример:
qs = Content.objects.instance_of(ProductA, ProductB)
Возврат:
<PolymorphicQuerySet [<ProductA: First Product A>, <ProductB: First Product B>]>
Поскольку продукт A и B оба имеют price, я подумал, что могу сделать:
qs.aggregate(total=Sum('price'))
но это приводит к ошибке:
django.core.exceptions.FieldError: Cannot resolve keyword 'price' into field.
Choices are: id, note, polymorphic_ctype, polymorphic_ctype_id, post,
producta, productb, slug, title, user, user_id
Я попробовал следующее:
qs.aggregate(total=Sum(Coalesce('producta__price', 'productb__price')))
что дает правильный ответ (12,99 + 18,99 = 31,98)
{'total': Decimal('31.9800000000000')}
but I have never used Coalesce before, don't know what it's doing, or if it's reliable as a solution in this case. Documentation says "returns the first non-null value" which sounds like it would return the first price only, but it seems to return all values that are not null? If a product will always have a price, would Coalesce be a good choice for finding the total price value of products?
I wondered about using Q() but not sure how I would do that in this case.