Pergunta

Estou lutando para dar a cabeça no Orm do Django. O que eu quero fazer é obter uma lista de valores distintos dentro de um campo na minha mesa ... o equivalente a um dos seguintes:

SELECT DISTINCT myfieldname FROM mytable

(ou alternativamente)

SELECT myfieldname FROM mytable GROUP BY myfieldname

Eu pelo menos gostaria de fazê -lo o caminho do Django antes de recorrer ao SQL bruto. Por exemplo, com uma tabela:

id, rua, cidade

1, Main Street, casco

2, outra rua, casco

3, Bribble Way, Leicester

4, outra maneira, Leicester

5, High Street, Londidium

Eu gostaria de obter:

Hull, Leicester, Londidium.

Foi útil?

Solução

Diga que seu modelo é 'loja'

class Shop(models.Model):
    street = models.CharField(max_length=150)
    city = models.CharField(max_length=150)

    # some of your models may have explicit ordering
    class Meta:
        ordering = ('city')

Já que você pode ter o Meta classe ordering Conjunto de atributos, você pode usar order_by() sem parâmetros para limpar qualquer pedido ao usar distinct(). Veja a documentação em order_by()

Se você não deseja que nenhum pedido seja aplicado a uma consulta, nem mesmo a ordem padrão, ligue para o pedido_by () sem parâmetros.

e distinct() na nota em que discute questões usando o uso distinct() com pedidos.

Para consultar seu banco de dados, você só precisa ligar:

models.Shop.objects.order_by().values('city').distinct()

Retorna um DictionNary

ou

models.Shop.objects.order_by().values_list('city').distinct()

Este retorna um ValuesListQuerySet que você pode lançar para um list. Você também pode adicionar flat=True para values_list Para achatar os resultados.

Veja também: Obtenha valores distintos de consulta por campo

Outras dicas

Além do ainda muito relevante Resposta de Jujule, Acho muito importante estar ciente das implicações de order_by() sobre distinct("field_name") Consultas. Este é, no entanto, um recurso Postgres apenas!

Se você estiver usando o Postgres e se você definir um nome de campo para o qual a consulta deve ser distinta, então order_by() precisa começar com o mesmo nome de campo (ou nomes de campo) na mesma sequência (pode haver mais campos depois).

Observação

Quando você especifica nomes de campo, você deve fornecer um order_by () no Queryset, e os campos em ordem_by () devem começar com os campos em distintos (), na mesma ordem.

Por exemplo, selecione distinto em (a) fornece a primeira linha para cada valor na coluna a. Se você não especificar um pedido, receberá uma linha arbitrária.

Se você deseja extrair uma lista de cidades nas quais você conhece lojas, o exemplo de Jujule teria que ser adaptado a isso:

# returns an iterable Queryset of cities.
models.Shop.objects.order_by('city').values_list('city', flat=True).distinct('city')  

Por exemplo:

# select distinct code from Platform where id in ( select platform__id from Build where product=p)
pl_ids = Build.objects.values('platform__id').filter(product=p)
platforms = Platform.objects.values_list('code', flat=True).filter(id__in=pl_ids).distinct('code')
platforms = list(platforms) if platforms else []
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top