Расширение функциональности фильтра для использования только в том случае, если переменная имеет значение
Я использую фреймворк django для создания приложения для блога.
моя версия django - Django version 4.0.4
Я должен отфильтровать данные в соответствии с заголовком и категорией, которая есть в блоге. мой код выглядит следующим образом
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')
Это работает идеально, но это не имеет смысла, поскольку не следует за DRY principle
Здесь я написал Blog.object.filter код дважды для поиска. поэтому я хочу минимизировать эту проблему в одной строке, если это возможно.
Так что не могли бы вы, ребята, помочь мне
Вы можете уменьшить это с помощью словаря
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')
Это очень просто, но одна строка была бы нечитабельна. .filter не посылает запрос, поэтому операции можно добавлять по одной. Простые "если" и несколько строк делают эту форму наиболее читабельной, которую можно получить здесь:
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
Oneliner, будет таким (поскольку пустая строка "" параметр в icontains возвращает все объекты):
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')
Примечание: я изменил имена, потому что camelCase в Python зарезервирован для имен классов, переменные должны использовать snake_case. Такова конвенция в любом случае.