/ / Django - como escrever esta consulta de uma forma que não requeira DISTINCT - django, django-models, query-optimization, django-queryset

Django - como escrever esta consulta de uma forma que não requer DISTINCT - django, django-models, otimização de consulta, django-queryset

Estou trabalhando com um modelo:

class Foo(models.Model):
name = models.CharField(max_length=255)
bars = models.ManyToManyField("Bar")

Em uma visão, tenho acesso a uma lista de Barobjetos e precisa obter todos Foo objetos que têm qualquer um dos Bar objetos em sua lista de bars, então eu faço isso:

foos = Foo.objects.filter(bars__in=list_of_bars)

O problema é que há duplicatas, se um Foo tem 2 barras, e ambas as barras estão em meu list_of_bars, que um simples distinct resolve:

foos = Foo.objects.distinct().filter(bars__in=list_of_bars)

Está tudo bem, exceto pelo acréscimo DISTINCT para a consulta torna-o muito lento, devido a haver 2 milhões Foo objetos no banco de dados.

Com tudo isso dito, de que maneira (s) você consegue pensar que não use DISTINCT, mas consegue o mesmo conjunto de resultados? Se envolver a alteração de modelos, tudo bem.

Respostas:

1 para resposta № 1

Você sempre pode selecionar únicos em python:

foos = set(Foo.objects.filter(bars__in=list_of_bars))

Você precisa de um conjunto de consultas. Então, talvez (apenas talvez) este hack rápido e desagradável possa ajudá-lo. É feio, mas talvez seja rápido (não tenho certeza disso).

def get_query_set(self):
foos = set(Foo.objects.filter(bars__in=list_of_bars))
return Foo.objects.filter(id__in=[f.id for f in foos])