1

I have a

Model Car(self.Models)
# a bunch of features here

then in my views.py, I get all the cars and compute a score for them:

allCars = Car.object.all() # so you get [A, B, C, D]
scoreList = someComputation(allCars) # returns [3,1,2,4]

then in my template I iterate through allCars to display them; using the ordering the query returned with I get primary key ordering, so

  1. A
  2. B
  3. C
  4. D

However I would like to know if there is a way to order the queryset using the list I computed in the view, which would yield

  1. B
  2. C
  3. A
  4. D

so doing something like

allCars.order_by(scoreList)
XenoChrist
  • 309
  • 1
  • 3
  • 11
  • Is that a random ordering, or is that a specific custom ordering ? If so, what is the logic ? – karthikr Aug 29 '16 at 14:07
  • In my particular case, a specific ordering based on features in the model (better safety rating adds to the score, less fuel efficiency subtracts from it, etc.). I'm using cars as just a generic example here. The same question stands for other orderings, although for random I know you could just order_by('?') – XenoChrist Aug 29 '16 at 14:09
  • If you need a good answer, you need to be more specific on what you are looking for. Example, what would be some example criteria you would sort by, etc.. – karthikr Aug 29 '16 at 14:11
  • Also, here is how you would do custom sorting on python lists: http://stackoverflow.com/questions/5213033/sort-list-of-list-with-custom-compare-function-in-python – karthikr Aug 29 '16 at 14:12

1 Answers1

3

First off, to answer your question, you can't use ORM/sql to sort something that's derived from the records with complex logic, unless it's just pure math, which database can do to some extent.

Your next option is to use python built in sorting. However, you can't sort items by a function that "take all in" and "spit all out", meaning your current function is taking a whole list and computed scores and return all scores, because you lost track of what score corresponds to which car.

I would use a function on the model to compute the score, then sort the records accordingly:

class Car(models.Model):
    @property
    def compute_score(self):
      return a_score_based_on_current_car

cars = Car.objects.all()
cars = sorted(cars, key=lambda car: car.compute_score)
Shang Wang
  • 24,909
  • 20
  • 73
  • 94
  • I see. if the logic for assigning score values also depends on records contained in other tables, then my only option is to extract the queryset to a python list and sort it that way before passing it to a template? I think it makes sense to me. – XenoChrist Aug 29 '16 at 14:31
  • 1
    Yea I'm afraid so, the method I provided could be done on any python list in general. It's just that you aren't sorting based on database fields so you couldn't leverage the power of database sorting, which might make things slower. But if that's your only option, then python sorting is the next best thing to have. – Shang Wang Aug 29 '16 at 14:36
  • That's a fair tradeoff to me. – XenoChrist Aug 29 '16 at 14:38