No Django, como um filtro um QuerySet com pesquisas de campo dinâmico?

votos
125

Dada uma classe:

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=20)

É possível, e se assim como, para ter um QuerySet que os filtros com base em argumentos dinâmicos? Por exemplo:

 # Instead of:
 Person.objects.filter(name__startswith='B')
 # ... and:
 Person.objects.filter(name__endswith='B')

 # ... is there some way, given:
 filter_by = '{0}__{1}'.format('name', 'startswith')
 filter_value = 'B'

 # ... that you can run the equivalent of this?
 Person.objects.filter(filter_by=filter_value)
 # ... which will throw an exception, since `filter_by` is not
 # an attribute of `Person`.
Publicado 22/11/2008 em 03:06
fonte usuário
Em outras línguas...                            


4 respostas

votos
230

expansão argumento de Python pode ser usado para resolver este problema:

kwargs = {
    '{0}__{1}'.format('name', 'startswith'): 'A',
    '{0}__{1}'.format('name', 'endswith'): 'Z'
}

Person.objects.filter(**kwargs)

Este é um idioma Python muito comum e útil.

Respondeu 22/11/2008 em 03:48
fonte usuário

votos
6

Django.db.models.Q é exatamente o que você quer de uma forma Django.

Respondeu 23/05/2013 em 16:55
fonte usuário

votos
6

Um exemplo simplificado:

Em um aplicativo de pesquisa Django, eu queria uma lista de seleção HTML mostrando utilizadores registados. Mas porque temos 5000 usuários registrados, eu precisava de uma maneira de filtrar essa lista com base em critérios de consulta (como apenas as pessoas que completaram uma determinada oficina). Para que o elemento de pesquisa para ser reutilizável, que eu precisava para a pessoa que cria a pergunta da pesquisa para ser capaz de anexar esses critérios para essa pergunta (não quero codificar a consulta para o aplicativo).

A solução que eu vim com não é 100% amigável (requer a ajuda de uma pessoa de tecnologia para criar a consulta), mas não resolve o problema. Ao criar a pergunta, o editor pode inserir um dicionário em um campo personalizado, por exemplo:

{'is_staff':True,'last_name__startswith':'A',}

Essa seqüência é armazenado no banco de dados. No código de vista, se trata novamente como self.question.custom_query. O valor de que é uma string que parece como um dicionário. Nós transformá-lo de volta em um verdadeiro dicionário com eval () e depois enchê-lo para o queryset com kwargs **:

kwargs = eval(self.question.custom_query)
user_list = User.objects.filter(**kwargs).order_by("last_name")   
Respondeu 18/03/2009 em 18:52
fonte usuário

votos
-1

Forma-se uma busca realmente complexas geralmente indica que um modelo mais simples está tentando cavar seu caminho para fora.

Como, exatamente, você espera para obter os valores para o nome e operação de coluna? De onde você tira os valores de 'name'um 'startswith'?

 filter_by = '%s__%s' % ('name', 'startswith')
  1. A "busca" forma? Você está indo - o quê? - escolher o nome de uma lista de nomes? Escolher a operação a partir de uma lista de operações? Enquanto aberto, a maioria das pessoas acham que este uso de difícil confuso e.

    Quantas colunas tem esses filtros? 6? 12? 18?

    • Um pouco? A pick-lista complexo não faz sentido. Alguns campos e alguns se-afirmações fazem sentido.
    • Um grande número? Seu modelo não parece certo. Parece que o "campo" é na verdade uma chave para uma linha em outra tabela, não uma coluna.
  2. botões de filtro específicos. Espera ... Essa é a forma de administração do Django funciona. filtros específicos são transformadas em botões. E a mesma análise que acima se aplica. Alguns filtros fazem sentido. Um grande número de filtros geralmente significa uma espécie de primeira forma violação normal.

Um monte de campos semelhantes, muitas vezes significa que deveria ter havido mais linhas e menos campos.

Respondeu 22/11/2008 em 03:36
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more