188👍
I loved Greg’s solution to this problem, but I’d like to point that you can do the same thing directly in the admin:
from django.db import models
class CustomerAdmin(admin.ModelAdmin):
list_display = ('number_of_orders',)
def get_queryset(self, request):
# def queryset(self, request): # For Django <1.6
qs = super(CustomerAdmin, self).get_queryset(request)
# qs = super(CustomerAdmin, self).queryset(request) # For Django <1.6
qs = qs.annotate(models.Count('order'))
return qs
def number_of_orders(self, obj):
return obj.order__count
number_of_orders.admin_order_field = 'order__count'
This way you only annotate inside the admin interface. Not with every query that you do.
52👍
I haven’t tested this out (I’d be interested to know if it works) but what about defining a custom manager for Customer
which includes the number of orders aggregated, and then setting admin_order_field
to that aggregate, ie
from django.db import models
class CustomerManager(models.Manager):
def get_query_set(self):
return super(CustomerManager, self).get_query_set().annotate(models.Count('order'))
class Customer(models.Model):
foo = models.CharField[...]
objects = CustomerManager()
def number_of_orders(self):
return u'%s' % Order.objects.filter(customer=self).count()
number_of_orders.admin_order_field = 'order__count'
EDIT: I’ve just tested this idea and it works perfectly – no django admin subclassing required!
- [Django]-Warning: Auto-created primary key used when not defining a primary key type, by default 'django.db.models.AutoField'
- [Django]-How to log all sql queries in Django?
- [Django]-How do I clone a Django model instance object and save it to the database?
0👍
The only way I can think of is to denormalize the field. That is – create a real field that get’s updated to stay in sync with the fields it is derived from. I usually do this by overriding save on eith the model with the denormalized fields or the model it derives from:
# models.py
class Order(models.Model):
bar = models.CharField[...]
customer = models.ForeignKey(Customer)
def save(self):
super(Order, self).save()
self.customer.number_of_orders = Order.objects.filter(customer=self.customer).count()
self.customer.save()
class Customer(models.Model):
foo = models.CharField[...]
number_of_orders = models.IntegerField[...]
- [Django]-Django rest framework change primary key to use a unqiue field
- [Django]-Django FileField upload is not working for me
- [Django]-Does django with mongodb make migrations a thing of the past?