I've got a model in a simple django app that records a score for people entering a competition. I've got two model objects, Entry and Person. Each Entry has a Person and a Person has multiple Entries.
I want to generate a page which shows each user, their total score and their rank.
The command I've got so far is as follows:
Entry.objects.values('person__name').annotate(total=Sum('score')).order_by('-total')
I can output the result of this onto the page nicely using a for block. The only thing I don't get is the rank.
What would be the best way of adding to each record the numerical rank of the record, including the fact that when two scores are the same, the rank reflects this (ie. "4=")? Would it be better to try and do this in the template using a forblock.counter and some loo开发者_开发百科kahead/behind mechanism, or to try and work this field into the query itself?
This sort of thing is very tricky. I would actually do all the work in the view, modifying the queryset there and passing it onto the template.
rank = 1
previous = None
entries = list(entries)
previous = entries[0]
previous.rank = 1
for i, entry in enumerate(entries[1:]):
if entry.value != previous.value:
rank = i + 2
entry.rank = str(rank)
else:
entry.rank = "%s=" % rank
previous.rank = entry.rank
previous = entry
Keep it simple, use the template loop.counter or loop.revcounter, don't mess with the query in this case I think.
You do not get anything more but person.name, because you specified that in values. Add total
and should be ok.
Entry.objects.values('person__name', 'total').annotate(total=Sum('score')).order_by('-total')
EDIT:
Another solution:
Person.objects.values('name').annotate(total=Sum('entries__score')).order_by('-total')
精彩评论