Django - queryset inválido depois cortando-
-
06-09-2019 - |
Pergunta
I buscar as últimas 5 linhas de um modelo Foo que é ordenado por um campo de data e hora.
qs = Foo.objects.all()[:5]
No passo seguinte, eu quero reordenar a queryset por alguns outros critérios (na verdade, pelo mesmo campo de data e hora na direção oposta). Mas reordenação depois de uma fatia não é permitido. reverse () desfaz a primeira ordenação, me dando um differet queryset. Existe uma maneira de conseguir o que eu quero, sem criar uma lista a partir do queryset e fazer a ordenação de usá-lo?
Solução
Não, não há nenhuma maneira de fazer isso. order_by
é uma operação no banco de dados, mas quando você corta um queryset é avaliada e não voltar para o banco de dados depois disso.
Parece que você já conhece a solução, no entanto:. Executar reversed()
nas qs avaliadas
qs = reversed(Foo.objects.all()[:5])
Outras dicas
order_by lhe dá SQL ordenação no banco de dados. Você já está usando isso, e então cortar nele. Nesse ponto, os resultados são recuperados na memória. Se você quiser alterar a sua ordem, você precisa usar Python de ordenação em memória de fazê-lo, não o ORM no banco de dados de classificação.
No seu caso, Daniel já deu a melhor solução: uma vez que você simplesmente deseja ordenar pelo mesmo campo, mas no outro fim, basta inverter a lista que você tem:
qs = Foo.objects.all()[:5]
objs = reversed(qs)
Se você queria ordenar por algum outro campo, então você pode usar a função classificadas () com uma função chave personalizado:
qs = Foo.objects.all()[:5]
objs = sorted(qs, key=lambda o: o.some_other_field)
resposta tardia, mas isso só funcionou para mim:
import random
sorted(queryset[:10], key=lambda x: random.random())