How to Dynamically Compose an or Query Filter in Django

How to dynamically compose an OR query filter in Django?

You could chain your queries as follows:

values = [1,2,3]

# Turn list of values into list of Q objects
queries = [Q(pk=value) for value in values]

# Take one Q object from the list
query = queries.pop()

# Or the Q object with the ones remaining in the list
for item in queries:
query |= item

# Query the model
Article.objects.filter(query)

How to dynamically compose an OR query filter in Django to delete pairs of objects from ManyToManyFields?

You can convert this into a Q object:

from django.db.models import Q

data = [
{'pizza': my_pizza, 'topping': pepperoni},
, {'pizza': your_pizza, 'topping': pepperoni1}
, {'pizza': your_pizza2, 'topping': mushroom}
]

PizzaToppingRelationship = Pizza.toppings.through
PizzaToppingRelationship.objects.filter(
Q(*[Q(**dati) for dati in data], _connector=Q.OR)
).delete()

How can I dynamically set Django filter in queryset

The technique you're missing has less to do with django and more to do with Python in general.

def myfunc1(arg1, arg2):
print(arg1, arg2)

def myfunc2(arg1=None, arg2=None):
print(arg1, arg2)

mylist = ['val1', 'val2']
mydict = {'arg1': 'val1', 'arg2': 'val2'}

Assuming you have the above:

myfunc1('val1', 'val2')
myfunc1(*mylist)

Are equivalent! Similarly:

myfunc2('val1', 'val2')
myfunc2(**mydict)

Are also equivalent!

You can pass a list into a function call as if they're the positional arguments with a single *, and you can pass a dictionary as keyword arguments with a double *

So ultimately what you want to do is build up a dictionary of things of the form:

filter_kwargs = {
'django_filter_kwarg_name': 'django_filter_value'
}

So for you this might be:

# build up the dictionary (or maybe you can do this off the form, request.GET, etc
filter_kwargs = {
'station_departure': ss_value,
'station_arrival': es_value,
....
}
# do something here to filter out the empty/None key/values
filter_kwargs = {key: value if value for key, value in filter_kwargs.items}
# now get the queryset
queryset = DailyReport.objects.all().filter(**filter_kwargs)

Dynamic filter on Django query

Create a dict with a dynamic key generated from given_field and then unpack it using ** to generate keywords arguments.

def search_engine(model, given_field, text):
# Stuff

filters = {
given_field+'__icontains': text
}
result = model.objects.filter(**filters)
return result

How to add filters to a query dynamically in Django?

Here's a bit more generic one. It will apply filters to your queryset if they are passed as the GET parameters. If you're doing a POST call, just change the name in the code.

import operator
from django.db.models import Q

def your_view(self, request, *args, **kwargs):
# Here you list all your filter names
filter_names = ('filter_one', 'filter_two', 'another_one', )

queryset = Books.objects.all();
filter_clauses = [Q(filter=request.GET[filter])
for filter in filter_names
if request.GET.get(filter)]
if filter_clauses:
queryset = queryset.filter(reduce(operator.and_, filter_clauses))

# rest of your view

Note that you can use lookup expressions in your filters' names. For example, if you want to filter books with price lower or equal to specified in filter, you could just use price__lte as a filter name.

Django make query dynamically for filter

Querying same field for different values(or condition) you can use __in key.

 possibilities = [1,2,3]
Article.objects.filter(field__in=posibilities)

Also for dynamic queries you can pass **kwargs to filter method:

query_key = 'your_field_name__in'
Article.objects.filter(**{query_key:[1,2,3]#your search value})

You can add your multiple model field into kwargs param:

query = {'field_1':value_1,'field_2':value_2,'field_3__contains':value_3}#for example
Article.objects.filter(**query)

In Django, how does one filter a QuerySet with dynamic field lookups?

Python's argument expansion may be used to solve this problem:

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

Person.objects.filter(**kwargs)

This is a very common and useful Python idiom.

How to dynamically filter with field name, condition and values in Django

After going through a few StackOverflow posts I figured out the logic. So below is the logic.

def get_filter(self, field_name, filter_condition, filter_value):
# thanks to the below post
# https://stackoverflow.com/questions/310732/in-django-how-does-one-filter-a-queryset-with-dynamic-field-lookups
# the idea to this below logic is very similar to that in the above mentioned post
if filter_condition.strip() == "contains":
kwargs = {
'{0}__icontains'.format(field_name): filter_value
}
return Q(**kwargs)

if filter_condition.strip() == "not_equal":
kwargs = {
'{0}__iexact'.format(field_name): filter_value
}
return ~Q(**kwargs)

if filter_condition.strip() == "starts_with":
kwargs = {
'{0}__istartswith'.format(field_name): filter_value
}
return Q(**kwargs)
if filter_condition.strip() == "equal":
kwargs = {
'{0}__iexact'.format(field_name): filter_value
}
return Q(**kwargs)

if filter_condition.strip() == "not_equal":
kwargs = {
'{0}__iexact'.format(field_name): filter_value
}
return ~Q(**kwargs)

def get(self, request):
# getting the array of objects data to filter. The array of objects data
# example is in the question
filter_data = request.query_params.getlist('filterData[]')

all_books = Books.objects.all()
# Creating initial Q object
filter_objects = Q()

# Looping through the array of objects
for data in filter_data:
# The main part. Calling get_filter and passing the filter object data.
filter_objects &= self.get_filter(
data["fieldName"], data["filterCondition"],
data["filterValue"])
filtered_data = all_books.filter(filter_objects)

Hope it helps someone. :)

For filtering data in Django, build dynamic query for multiple columns

Filter the request for non-empty values and then use dictionary expansion to do the query.

q =  {k:v for k, v in request.GET.items() if v}
sum_tt_count = NetworkRelatedInformation.objects.filter(**q).aggregate(Sum('tt_count'))


Related Topics



Leave a reply



Submit