Tuesday, June 1, 2010

admin recipe: sort on "computed fields", and a question?

I have had some complex pages for managers on my site that always had
problems. Now I'm trying to replace them with admin forms. I have
discovered that you can sort based on "follow" notation, and this can
include aggregates. I thought I'd post this undocumented feature: is
it a "real" feature -- should it be documented? Or is it a side-effect
of the current implementation? Note that it doesn't seem to work for
"computed fields" -- tacked onto the query set using extra()... I
wonder if this is a bug?

To clarify what I'm talking about by example: suppose I have the
following models:

from django.contrib.auth.models import User

class Profile( User ):

...

class Account( models.Model ):

profile = models.OneToOneField( Profile )

class Order( models.Model ):

needs_confirm = models.BooleanField( default = True )
sub_total = models.DecimalField( )
tax = models.DecimalField()

------------
Now, to make the admin list of profiles sortable by whether needs
confirm, the following works:

class AdminProfileManager( models.Manager ):
def get_query_set( self ):
q = super( AdminProfileManager, self ).get_query_set()
q = q.annotate(
needs_confirmation =
BoolOr( 'account__orders__needs_confirm' ) )
return q

class AdminProfile( Profile ):
objects = AdminProfileManager()

class Meta:
proxy = True

def confirmed( self ):
return not self.needs_confirmation
confirm.admin_order_field = '-needs_confirmation'
confirm.boolean = True

class ProfileAdmin( admin.ModelAdmin ):
list_display = (
'first_name', 'last_name', 'email', 'is_active',
'confirmed' )

--------
Now it will sort by whether we need confirmation (btw, the aggregate
BoolOr is defined following the
recipe in http://groups.google.com/group/django-users/browse_thread/thread/bd5a6b329b009cfa
)
--------
However, I can't get it to accept sorting by an field added to the
queryset with extra(), eg. (in AdminProfileManager.queryset )

q = q.annotate( subtotal = Sum( 'account__orders__sub_total' )
q = q.annotate( tax = Sum( 'account__orders__tax' ) )
q = q.extra( select = dict( revenue = 'subtotal + tax' ) )

If I refer to "revenue" in an "admin_order_field" attribute... even if
I replace the complex expression with a dummy select that merely
renames some existing field. Is there some other way to do this? Is
this a good candidate for enhancement (should I move over to
"developers" or open a ticket?)?

Thanks!

-- Shaunc

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to django-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

No comments:

Post a Comment