Request when django parameter is missing

I want to make a request, something like

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

... but there are some cases where, for example, y is None. This literally looks for a database for null values ​​in the y column - is there a great way to substantially ignore this query parameter if it is not, i.e. returns a query

 Model.objects.filter(x=x).filter(z=z)? 
+8
python django mysql django-models
source share
5 answers

I don't know if I get your question, but

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

gives you a query where the column y not null ( IS NOT NULL ).

Here is the relevant documentation.

EDIT: check that y is None and dynamically create your query:

 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 solve, you can use something like this; assuming x , y , z are stored in your values dictionary:

 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) 
+11
source share

Something like this might 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 , it is not related to database activity.

+4
source share

You can create a model manager and assign it to your model so that you can use this manager for 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 opinion, you can use the above manager as:

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

Now you do not need to worry about any values ​​:) hope this help.

+2
source share

The best approach to an otherwise very readable answer to the question is:

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

In any case, depending on the specific filter, you will need to apply the filters together in one call .filter (), so the "blind" method works only in simple cases. See https://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-multi-valued-relationships for more details.

+1
source share

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) 
0
source share

All Articles