[Fixed]-Django sorting/order_by a list of model objects with a computed value

1👍

You may need to tweak this for related names and the like but something like the below should help. If I understand you correctly you need yourSlot objects to be aware of their User‘s Appointment counts.

# define as a method of your Slot class
def user_appointment_count(self):
    return [(x, x.appointment_set.count()) for x in self.user_set.all()]

That will return a list of 2-tuples, where the first item is the user and the second is their appointment count. Taking the first two items in such a list will give you the two related users with the fewest appointments for any given slot. Remember to handle cases where there are fewer than 2 people in the list, or where there are ties in the appointment count.

I might add another model method for just that along the lines of:

def relevant_appointment_count(self):
    return sum(x[1] for x in self.user_appointment_count()[:2])

You would combine this with something similar to the suggestion in my first comment as a queryset (either as extra context or as the main queryset depending on your preference) if you want to sort slots by how few appointments their two users from the above have.

# use this perhaps to return a queryset or extra context in a view
return sorted(
    Slot.objects.filter(is_matched=False),
    key=lambda s: s.relevant_appointment_count(),
    reverse=True
)

That should (haven’t tested so again, may need a slight tweak) return a list of slots in the order I’ve described. Again you’d need to handle the same cases I described before.

Leave a comment