Quem sou eu

Minha foto

Formado em Computação, desenvolvedor web, interessado em tecnologia, metaleiro e um gamer inveterado.

Pesquisar

terça-feira, 27 de setembro de 2011

Como ordenar uma listagem de produtos pelos mais recentes, deixando os esgotados pro fim?

Recentemente tive que fazer a ordenação descrita no título deste post.

A solução encontrada foi a utilização da poderosa ferramenta extra que o django oferece em seu ORM.

Tinha a seguinte situação:

models.py

class Produto(models.Model):
     ...
     ...
     estoque = models.IntegerField()
     ...
     ...


Meu campo estoque gerencia a quantidade disponível de cada produto na loja. 

Fiz da seguinte forma no meu arquivo view.py:

def lista_produto(request):
     ...
     ...
     produtos = Produto.objecst.all().extra(select={'esgotado': "( if (produtos_produto.estoque > 0,0,-10000) )+produtos_produto.id"}).extra( order_by = ['-esgotado'] )
     ...
     ...

Juntamente com todos os campos da classe Produto, crio um campo a mais para o retorno, sendo este chamado de esgotado. Para este campo será executado a query passada a seguir para o banco de dados:

 if (produtos_produto.estoque > 0,0,-10000) )+produtos_produto.id

Caso o estoque for maior que 0, o IF irá retornar 0, caso contrário será retornado -10000. O valor negativo aqui é arbitrário, podendo este ser qualquer valor, desde que seu módulo seja pelo menos igual ao maior id do banco.



Ao valor do IF é adiconado o ID do produto corrente.

Desta forma todos os produtos que não tiverem estoque, será trazido neste campo um valor negativo visto que a conta ficará -10000 + ID,  e os que possuírem algum estoque, será 0 + ID.

Finalmente, passamos a nova ordenção, esgotado DESC, também pelo extra:
.extra( order_by = ['-esgotado'] )

Assim, todos os produtos com estoque ficarão com um valor positivo para o valor esgotado, e os que não tiverem, será um valor negativo, ficando por últimos com a ordenação decrescente.

hasta!