32
Maybe you don’t need this answer now, but if you read the documentation about Sum expression , you need to declare the output_field
, like this:
Customer.objects.filter(something)
.annotate(total_spent=Sum(
F('order__lineitem__quantity') *
F('order__lineitem__price'),
output_field=models.FloatField()
))
2
You could try using a property in the LineItem
model:
class Lineitem(models.Model):
order = models.ForeignKey(Order)
quantity = models.IntegerField(blank=True)
price = models.DecimalField(max_digits=6, decimal_places=2)
def _get_total(self):
return quantity * price
total = property(_get_total)
Then I think you can annotate with the total amount spent using
Customer.objects.filter(something).annotate(total_spent=Sum('order__lineitem__total'))
I don’t know how the efficiency of this method relates to others, but it is more Pythonic/Django-y than the alternative, which is to write the entire SQL query by hand as in
Customer.objects.raw("SELECT ... from <customer_table_name> where ...")
- [Django]-Is virtualenv recommended for django production server?
- [Django]-How to completely dump the data for Django-CMS
- [Django]-Is not JSON serializable
- [Django]-Error 111 connecting to localhost:6379. Connection refused. Django Heroku
- [Django]-How to make an auto-filled and auto-incrementing field in django admin
- [Django]-Django models: get list of id
1
You’ll probably need to roll out your own custom aggregator. You can find a simple walk through of a GROUP_CONCAT
example that should get you started here:
http://harkablog.com/inside-the-django-orm-aggregates.html
- [Django]-Django – why is the request.POST object immutable?
- [Django]-Django test RequestFactory vs Client
- [Django]-Why does django run everything twice?
0
I just ran into this and I don’t think that annotate and will work with a property, see Django – Can you use property as the field in an aggregation function?
Here is what I did.
class Customer(models.Model):
email = models.CharField(max_length=128)
class Order(models.Model):
customer = models.ForeignKey(Customer)
order_status = models.CharField(blank=True, max_length=256)
class Lineitem(models.Model):
order = models.ForeignKey(Order)
quantity = models.IntegerField(blank=True)
price = models.DecimalField(max_digits=6, decimal_places=2)
@property
def total(self):
return self.quantity * self.price
Then use sum and a list comprehension:
sum([li.total for li in LineItem.objects.filter(order__customer=some_customer).filter(somefilter)])
- [Django]-Celery: When should you choose Redis as a message broker over RabbitMQ?
- [Django]-How to create an object for a Django model with a many to many field?
- [Django]-Troubleshooting Site Slowness on a Nginx + Gunicorn + Django Stack
0
Similar to: https://stackoverflow.com/a/19888120/1344647
from django.db.models import Sum
q = Task.objects.filter(your-filter-here).annotate(total=Sum('progress', field="progress*estimated_days"))
Edited: Thanks to @Max, using annotate instead aggregated.
- [Django]-Django. A good tutorial for Class Based Views
- [Django]-How can I get the object count for a model in Django's templates?
- [Django]-How to test custom django-admin commands