Quiero hacer una consulta, algo como

Model.objects.filter(x=x).filter(y=y).filter(z=z) 

... pero hay algunos casos en que, por ejemplo, y es Ninguno. Esto literalmente busca valores nulos en la base de datos en la columna y: ¿hay una manera ingeniosa de ignorar esencialmente ese parámetro de consulta si no es ninguno, es decir, devolver el conjunto de consultas?

Model.objects.filter(x=x).filter(z=z)?
12
Brian D 10 ago. 2011 a las 10:45

5 respuestas

La mejor respuesta

No sé, si recibo tu pregunta, pero

Model.objects.filter(x=x, y__isnull = False, z=z)

Le proporciona el conjunto de consultas, donde la columna y no es nula (IS NOT NULL).

Aquí se encuentra la documentación relevante.

EDITAR: compruebe si y es None y cree su conjunto de consultas dinámicamente:

if y is None:
    qs = Model.objects.filter(x=x).filter(z=z)
elif z is None:
    qs = Model.objects.filter(x=x).filter(y=y)
...

Si hay demasiados argumentos con los que lidiar, podría usar algo como esto; suponiendo que x, y, z se almacenan en un diccionario your values:

your_values = { 'x' : 'x value', 'y' : 'y value', 'z' : 'value'}
arguments = {}
for k, v in your_values.items():
    if v:
        arguments[k] = v

Model.objects.filter(**arguments)
15
jazz 10 ago. 2011 a las 07:17

Puedes escribir:

filters = {'x':'abc', 'y':None, 'z':2}
# here we filter out the None values of the dict 
filters = dict(filter(lambda (k, v): v is not None, filters.items()))

# We use the dict to create the query
qs = Model.objects.filter(**filters)
0
recamshak 10 ago. 2011 a las 12:35

Un mejor enfoque en la respuesta de otra manera muy legible @ rolling-stone:

models = Model.objects.all()

variables = {'x':x,'y':y,'z':z}

for key, value in variables.items():
    if value is not None:
        models = models.filter(**{key: value})

De todos modos, dependiendo del filtro específico, necesitará aplicar filtros juntos en la misma llamada .filter (), por lo que la forma "ciega" solo funciona en los casos simples. Ver https://docs.djangoproject.com / es / dev / topics / db / queries / # spanning-multi-valued-relations para obtener más información sobre esos casos.

1
rewritten 10 ago. 2011 a las 10:42

Puede crear un administrador de modelos y luego asignarlo a su modelo para que pueda usar este administrador en cualquier modelo. Esta solución es más pitónica.

class GridManager(models.Manager):

    def applyFilters(self, *args, **kwargs):
         new_kwargs = {}
         for eachKey in kwargs:
             val = kwargs[eachKey]
             if val != '' and val != None:
                 new_kwargs[eachKey] = val
         if new_kwargs:
             return super(GridManager, self).get_query_set().filter(*args, **new_kwargs)
         else:
             return super(GridManager, self).get_query_set()

Asigne este administrador a su modelo:

class some_model(models.Model):
     your fields.....
     ......
     objects = models.Manager()
     grid_manager = GridManager()

Y en su opinión, puede usar el administrador anterior como:

objects = some_model.grid_manager.applyFilters(x=value, y = value, z = None)

Ahora no tiene que preocuparse por los valores none. Espero que esto ayude.

2
Mihai Chelaru 30 may. 2019 a las 13:01

Algo como esto podría funcionar:

models = Model.objects.all()

variables = {'x':'x','y':'y','z':'z'}

for key, value in variables.items():
    if key=='x' and value:
        models = models.filter(x=value)
    if key=='y' and value:
        models = models.filter(y=value)
    if key=='z' and value:
        models = models.filter(z=value)

Debido a que QuerySets son perezosos, esto no ' No involucra ninguna actividad de la base de datos.

4
rolling stone 10 ago. 2011 a las 07:11