Por lo que sé, no hay una solución genérica de Django para esto. Puede reducir su uso de memoria y limitar sus consultas de base de datos mediante la creación de una estructura de búsqueda id/question_code
from natsort import natsorted
question_code_lookup = Question.objects.values('id','question_code')
ordered_question_codes = natsorted(question_code_lookup, key=lambda i: i['question_code'])
Suponiendo que desea paginar los resultados, puede dividir los códigos_de_preguntas_ordenados, realizar otra consulta para recuperar todas las preguntas que necesita ordenarlas según su posición en ese segmento
#get the first 20 questions
ordered_question_codes = ordered_question_codes[:20]
question_ids = [q['id'] for q in ordered_question_codes]
questions = Question.objects.filter(id__in=question_ids)
#put them back into question code order
id_to_pos = dict(zip((question_ids), range(len(question_ids))))
questions = sorted(questions, key = lambda x: id_to_pos[x.id])
Si la estructura de búsqueda todavía utiliza demasiada memoria o tarda demasiado en ordenarse, tendrá que pensar en algo más avanzado. Esto ciertamente no escalaría bien a un gran conjunto de datos