I have a requirement, that is from the client side I will get an array of objects which will have field names, filtering conditions and the filtering values like this.
Sample array of objects:
[
{field_name: "book_name", filter_condition: "contains", filter_value: "some book name"},
{field_name: "book_category", filter_condition: "not_equal", filter_value: "category value"},
{field_name: "book_author", filter_condition: "starts_with", filter_value: "authoer name"},
{field_name: "book_price", filter_condition: "equal", filter_value: 100}
]
and I've to filter based on all of the above conditions. Consider I have a model with name Book and the fields which are there in the array of objects (i.e. book_name, book_category, book_author, book_price). For filter_condition I've written a function that compares the filter_condition and assigns the Django queryset API. For example.
def assign_filter_condition(self, request, filter_condition, field_name, filter_value):
if filter_condition == "contains":
kwargs = {
'{0}__icontains'.format(field_name): filter_value
}
return kwargs
...
Here I don't know how to apply conditions for exclude and NOT query.
I'm really not understanding how to write the logic for this. can anyone please help with the logic.
Thank you in advance.
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. :)