Query when parameter is none django

蓝咒 提交于 2020-01-01 02:17:09

问题


I want to make a query, something like

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

... but there are some cases when for example y is None. This literally searches the database for null values in the y column -- is there a nifty way to essentially disregard that query parameter if it is none, i.e. return the queryset

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

回答1:


I do not know, if I get your question, but

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

gives you the queryset, where the ycolumn is non-null (IS NOT NULL).

Here's the relevant documentation.

EDIT: Check if y is None and build your queryset dynamically:

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)
...

If there are too many arguments to deal with, you could use something like this; assuming that x, y, z are stored in a dictionary 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)



回答2:


Something like this could work:

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)

Because QuerySets are lazy, this doesn't involve any database activity.




回答3:


You can create a model manager and then assign it to your model so that you can use this manager to any model. This solution is more pythonic.

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()

Assign this manager to your model:

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

And in your view you can use the above manager as:

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

Now you don't have to worry about the none values. Hope this helps.




回答4:


A better approach on the otherwise very readable @rolling-stone answer:

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})

Anyway, depending on the specific filter, you'll need to apply filters together in the same .filter() call, so the "blind" way only works in the simple cases. See https://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-multi-valued-relationships for more information on those cases.




回答5:


You can write:

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)


来源:https://stackoverflow.com/questions/7006862/query-when-parameter-is-none-django

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!