then how do I then sort the QuerySet returned by title?
I can't do an .. object_list = products.items().sort('title')
because I have already done a [:100] on the results...
thanks
tom
... answering my own question but this works... probably will be slow
for a large collection of objects but it's useful for making a
tagcloud (unfinished)..
def tagcloud(request):
def sort(objects, sortAttrib):
sortValues = [(getattr(objects[i], sortAttrib), i) for i in range
(len(objects))]
sortValues.sort(), # Sorts by first value in tuple
return [objects[sortTuple[1]] for sortTuple in sortValues]
words = Word.objects.all().order_by('value').order_by('-
product_count')[:100] # I have calculated these before-hand by
splitting product.name into words and creating 2 tables (word and
product_word)
big_num = words[0].product_count # get the biggest
for word in words:
word.percentage = ((word.product_count * 100) / big_num) + 10 #
the 10 is a hack so the fonts don't disappear....
words = sort(words, 'value') #see above
return render_to_response('tagcloud.html', add_defaults
( {'object_list':words} ) )
{% for word in object_list %}
<font style="font-size:{{word.percentage}}px;vertical-
align:middle;"><a href="{{BASE_URL}}words/{{word.value}}/"
title="{{word.product_count}} items">{{word.value}}</a></
font>
{% endfor %}
Are you wanting the same 100 results you got in the first query just
ordered by title, or are you looking for a different 100 results based
on the order by title?
If you are looking for a different list of a 100 results, which is how
I'm taking your email, then you'd need to do another query where the
results are ordered by the title. The only other way would be to
return all the records in the first result instead of limiting it to
100 and then you could sort based on the columns and grab the first
100 records, but I would guess this method would would most likely be
more expensive than doing two separate queries to the DB (specially if
there are a lot of records).
--James
In the long run, it may be better to perform another query :)
--
Marko
ICQ: 5990814
I'm not under the alkafluence of inkahol
that some thinkle peep I am.
It's just the drunker I sit here the longer I get.
I want to find my top 100 words (by product_count) then sort them
alphabetically.... to make a tag cloud...
thanks...
If you are only dealing with 100 records after the query, then its not
a big deal to just sort them by some property in memory. Something
like:
# get the top 100 objects by the first criteria
object_list = Word.objects.all().order_by('-product_count')[:100]
# create a dict of the second criteria -> index of the current list
index = dict([(word.value, i) for i, word in enumerate(object_list)])
# get a new list of objects ordered by the second criteria
sorted_object_list = [object_list[index[key]] for key in
sorted(index.keys())]
I think I got all that syntax right...
-Dave
object_list = Word.objects.all().order_by('-product_count')[:100]
object_list.sort(key=lambda w: w.title)
--Ned.
If you are only dealing with 100 records after the query, then its not
a big deal to just sort them by some property in memory. Something
like:
# get the top 100 objects by the first criteria
object_list = Word.objects.all().order_by('-product_count')[:100]
# create a dict of the second criteria -> index of the current list
index = dict([(word.value, i) for i, word in enumerate(object_list)])
# get a new list of objects ordered by the second criteria
sorted_object_list = [object_list[index[key]] for key in
sorted(index.keys())]
I think I got all that syntax right...
-Dave
.
-- Ned Batchelder, http://nedbatchelder.com
Time these things before worrying about whether they are too slow. You
are only dealing with 100 items and sorting in Python is a fast
operation. The geniuses behind the code have put a lot of work into
making it go like the wind (on a very windy day). As a general rule, if
you can reduce a Python algorithm to something based on sorting, you are
going to be very happy.
> def tagcloud(request):
>
> def sort(objects, sortAttrib):
> sortValues = [(getattr(objects[i], sortAttrib), i) for i in range
> (len(objects))]
> sortValues.sort(), # Sorts by first value in tuple
> return [objects[sortTuple[1]] for sortTuple in sortValues]
>
> words = Word.objects.all().order_by('value').order_by('-
> product_count')[:100] # I have calculated these before-hand by
> splitting product.name into words and creating 2 tables (word and
> product_word)
> big_num = words[0].product_count # get the biggest
>
> for word in words:
> word.percentage = ((word.product_count * 100) / big_num) + 10 #
> the 10 is a hack so the fonts don't disappear....
> words = sort(words, 'value') #see above
You can be a little more efficient than this. The built in sort() method
on a list takes an optional comparator function that compares two items
at a time. So you could throw away your sort function and replace it
with
words = list(words)
words.sort(lambda lhs, rhs: cmp(lhs.value, rhs.value))
which would save a couple of passes over the list. In Python 2.4, you
can also get a little bit more speed using the "key" attribute to sort()
or using the sorted() method (see the Python docs for details on those).
Cheers,
Malcolm