vendredi 14 novembre 2014

python - Django get_queryset() peine à créer plusieurs étiquettes d'annotation - Stack Overflow


I am trying to get a few different annotation results to show in the Django Admin. I need these new results to be sortable columns as well. I came up with this (after reading EXTENSIVELY on SO):


def queryset(self, request):
qs = super(BrandAdmin, self).get_queryset(request)
qs = Brand.objects.annotate(
last_connection=Max('account__computer__last_connect')
).filter(
account__computer__last_connect__gte=(datetime.datetime.now() - datetime.timedelta(weeks=4))
).annotate(
brand_count=Count('account__computer')
)
return qs

def billable_computers(self, obj):
return obj.brand_count
billable_computers.admin_order_field = 'brand_count'

def last_connection(self, obj):
return obj.last_connection
last_connection.admin_order_field = 'last_connection'

This works, but returns with really weird (multiplied by some factor) results for the 'billable_computers'. I figured this was because of the chained annotations.


So I tried this:


def queryset(self, request):
qs = super(BrandAdmin, self).get_queryset(request)
qs = Brand.objects.filter(
account__computer__last_connect__gte=(datetime.datetime.now() - datetime.timedelta(weeks=4))
).all().distinct().annotate(
brand_count=Count('account__computer')
)
qss = super(BrandAdmin, self).get_queryset(request)
qss = Brand.objects.annotate(
last_connection=Max('account__computer__last_connect')
)
qs_all = qs | qss
return qs_all

def billable_computers(self, obj):
return obj.brand_count
billable_computers.admin_order_field = 'brand_count'

def last_connection(self, obj):
return obj.last_connection
last_connection.admin_order_field = 'last_connection'

But this causes an error complaining that "'Brand' object has no attribute 'last_connection'".


So I tried this:


def queryset(self, request):
qs = super(BrandAdmin, self).get_queryset(request)
qs = Brand.objects.filter(
account__computer__last_connect__gte=(datetime.datetime.now() - datetime.timedelta(weeks=4))
).annotate(
brand_count=Count('account__computer')
)
qs = Brand.objects.annotate(
last_connection=Max('account__computer__last_connect')
)
return qs

But this give a "'Brand' object has no attribute 'brand_count'" error.


About the models: The Computer model has a foreign key to Account and Account has a foreign key to Brand. The Computer model has a datetime field labeled 'last_connect'. Every Brand can have unlimited Accounts and every Account can have unlimited Computers.


I just need to tally all the Computers (at each level) that have connected in the last 4 weeks. I also need a separate (sortable) column for the latest 'last_connect' value across all computers in the unfiltered set.


Obviously I am getting this wrong, but it seems like it should be so simple. I need two different metrics. I want to query them in the Admin and not at the model level. I don't want to make my models any more complicated than they are now.


Any advice is welcome! Thank you!



I am trying to get a few different annotation results to show in the Django Admin. I need these new results to be sortable columns as well. I came up with this (after reading EXTENSIVELY on SO):


def queryset(self, request):
qs = super(BrandAdmin, self).get_queryset(request)
qs = Brand.objects.annotate(
last_connection=Max('account__computer__last_connect')
).filter(
account__computer__last_connect__gte=(datetime.datetime.now() - datetime.timedelta(weeks=4))
).annotate(
brand_count=Count('account__computer')
)
return qs

def billable_computers(self, obj):
return obj.brand_count
billable_computers.admin_order_field = 'brand_count'

def last_connection(self, obj):
return obj.last_connection
last_connection.admin_order_field = 'last_connection'

This works, but returns with really weird (multiplied by some factor) results for the 'billable_computers'. I figured this was because of the chained annotations.


So I tried this:


def queryset(self, request):
qs = super(BrandAdmin, self).get_queryset(request)
qs = Brand.objects.filter(
account__computer__last_connect__gte=(datetime.datetime.now() - datetime.timedelta(weeks=4))
).all().distinct().annotate(
brand_count=Count('account__computer')
)
qss = super(BrandAdmin, self).get_queryset(request)
qss = Brand.objects.annotate(
last_connection=Max('account__computer__last_connect')
)
qs_all = qs | qss
return qs_all

def billable_computers(self, obj):
return obj.brand_count
billable_computers.admin_order_field = 'brand_count'

def last_connection(self, obj):
return obj.last_connection
last_connection.admin_order_field = 'last_connection'

But this causes an error complaining that "'Brand' object has no attribute 'last_connection'".


So I tried this:


def queryset(self, request):
qs = super(BrandAdmin, self).get_queryset(request)
qs = Brand.objects.filter(
account__computer__last_connect__gte=(datetime.datetime.now() - datetime.timedelta(weeks=4))
).annotate(
brand_count=Count('account__computer')
)
qs = Brand.objects.annotate(
last_connection=Max('account__computer__last_connect')
)
return qs

But this give a "'Brand' object has no attribute 'brand_count'" error.


About the models: The Computer model has a foreign key to Account and Account has a foreign key to Brand. The Computer model has a datetime field labeled 'last_connect'. Every Brand can have unlimited Accounts and every Account can have unlimited Computers.


I just need to tally all the Computers (at each level) that have connected in the last 4 weeks. I also need a separate (sortable) column for the latest 'last_connect' value across all computers in the unfiltered set.


Obviously I am getting this wrong, but it seems like it should be so simple. I need two different metrics. I want to query them in the Admin and not at the model level. I don't want to make my models any more complicated than they are now.


Any advice is welcome! Thank you!


0 commentaires:

Enregistrer un commentaire