def sort_helper(object_list, sort_list, db_field_map=None): """ Helper method for sorting object_lists. @param object_list An array of objects to sort. @param sort_list An array of names to sort by. @param db_field_map An optional dictionary that maps a sort name to an object's property or method. @return The sorted list """ def clean(x): """ Function that cleans the value to sort by. @param x The attribute on the object. @return The cleaned up value for sorting. """ # attribute is a method so get the returned value v = x() if callable(x) else x # attribute is a string so convert it to lower case if type(v) == str or type(v) == unicode: v = v.lower() # attribute is a datetime so convert it to an epoch value elif type(v) == datetime.datetime: v = time.mktime(v.timetuple()) # return the value return v # reverse the sort order so we get the correct sub-sorting sort_order = reversed(sort_list) # Generate the actual list of attributes we'll be sorting by for sort_item in sort_order: # -name so sort this attribute descending if sort_item[0] == '-': base_sort_item = sort_item[1:] reverse = True # Otherwise sort in ascending order else: base_sort_item = sort_item reverse = False # Check if the name is in the db field map if db_field_map: if not base_sort_item in db_field_map: continue db_field = db_field_map[base_sort_item] else: db_field = base_sort_item # Do the actual sort now try: object_list = sorted(object_list, key=lambda x: clean(getattr(x, db_field)), reverse=reverse) except Exception, e: logging.exception('sort_helper - %s' % unicode(e)) return object_list