I am using the django framework for make an blog app.
my django version is Django version 4.0.4
i am supposed to do filter the data as per Title And category that blog does have my code is as follow
searchTitle = request.GET.get('searchTitle')
searchCat = request.GET.get('searchCat', '')
if searchTitle or searchCat:
blogs = Blog.objects.filter(blog_title__icontains=searchTitle).order_by('-blog_id')
if searchCat:
blogs = Blog.objects.filter(blog_title__icontains=searchTitle,blog_category=searchCat).order_by('-blog_id')
else:
blogs = Blog.objects.all().order_by('-blog_id')
This is working perfect but this doesn't make sense since it does not follow DRY principle
Here i've written Blog.object.filter
code twice for search. so i want to minimize that and that problem in one line if possible.
so could you guys guide over me
CodePudding user response:
You can reduce this using dictionary
searchTitle = request.GET.get('searchTitle')
searchCat = request.GET.get('searchCat', '')
d = {}
if searchTitle or searchCat:
d.update({"blog_title__icontains": searchTitle})
if searchCat:
d.update({"blog_category": searchCat})
if d:
Blog.objects.filter(**d).order_by("-blog_id")
else:
blogs = Blog.objects.all().order_by('-blog_id')
CodePudding user response:
This is very simple, but a single line would not be readable. .filter
doesn't send a query, so the operations can be added one by one. Simple ifs and a few lines make it the most readable form you can achieve here:
search_title = request.GET.get('searchTitle')
search_cat = request.GET.get('searchCat', '')
blogs = Blog.objects.all().order_by('-blog_id') # no query sent to db
if search_title:
blogs = blogs.filter(blog_title__icontains=search_title) # no query sent
if search_cat:
blogs = blogs.filter(blog_category=search_cat) # no query sent
blog_ids = [blog.id for blog in blog] # single query sent here
The oneliner, would be this (since empty string ""
parameter in icontains
returns all objects):
search_title = request.GET.get('searchTitle', '')
search_cat = request.GET.get('searchCat', '')
blogs = Blog.objects.filter(
blog_title__icontains=search_title,
blog_category=search_cat,
).order_by('-blog_id')
Note: I have changed the names, because camelCase in Python is reserved for class names, variables should use snake_case. That's the convention anyway.