Como fornecer dinamicamente nome campo de pesquisa na consulta Django? [duplicado]

StackOverflow https://stackoverflow.com/questions/1227091

  •  22-07-2019
  •  | 
  •  

Pergunta

Esta questão já tem uma resposta aqui:

Eu quero olhar para uma determinada seqüência em vários campos de um modelo no Django. Idealmente, seria algo semelhante a:

keyword = 'keyword'
fields = ['foo', 'bar', 'baz']
results = []
for field in fields:
    lookup = "%s__contains"
    results.append(Item.objects.filter(lookup=keyword))

É claro que isso não vai funcionar, como "pesquisa" não pode ser resolvido em um campo. Existe alguma outra maneira de fazer isso?

Foi útil?

Solução

Eu acho que pode haver uma maneira melhor de fazer isso com o sistema de consulta Django. Aqui está como fazê-lo à sua maneira.

Python permite que você passe dicionários para ser usado como argumento listas prefixando-los com **. Com um pouco de sorte, você deve ser capaz de fazer algo parecido com isto:

lookup = "%s__contains" % field
results.append(Item.objects.filter(**{ lookup: keyword}))

Outras dicas

Eu preferiria usar o objeto Q para algo como isto.

from django.db.models import Q

keyword = 'keyword'
fields = ['foo', 'bar', 'baz']

Qr = None
for field in fields:
    q = Q(**{"%s__contains" % field: keyword })
    if Qr:
        Qr = Qr | q # or & for filtering
    else:
        Qr = q

# this you can now combine with other filters, exclude etc.    
results = MyModel.objects.filter(Qr)

Eu gosto de resposta de DialZ mas por motivos de desempenho você deve construir a consulta e, em seguida, bater o banco de dados uma vez ao invés de concatenar todos os resultados em uma lista:

keyword = 'keyword'
fields = ['foo', 'bar', 'baz']

# this makes an empty queryset object which we can
# add to later using the | operator
results = Item.objects.none()

for field in fields:
    lookup = "%s__contains" % field
    query = {lookup : keyword}
    results = results | Item.objects.filter(**query)

Eu havn't feito um destes em um tempo, mas eu tenho certeza que Django não vai realmente bater o banco de dados em todo este código. Ele só vai realizar uma consulta quando você acessar os dados contidos nos registros

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top