Как использовать одно и то же представление списка для поиска и набора запросов по категориям в django
Я пытаюсь построить функциональность в моем приложении Django, в котором мы можем получать данные двумя методами:
- Using Search
- Selecting a Category
Поскольку в обоих случаях требуется получить данные из набора данных, мне интересно, есть ли способ использовать тот же ListView (не CBV) для вывода данных.
urls.py
path('datalist/<slug:category_slug>/' views.problemlist, name="problem_list_category"),
path('datalist/search/' views.problemlistbysearch, name="problem_list_search"),
views.py
def problemlist(request, category_slug):
qs = DataModel.objects.get(category_slug=category_slug)
return render(request,'list.html',{'qs':qs} )
def problemlistbysearch(request):
if request.method == 'GET':
querry = request.GET.get('name')
objlst = DataModel.objects.all()
qs = objlst.filter(title__icontains=querry)
return render(request, 'seach.html', {'qs':qs})
Function-based View (FBV)
Вы можете позволить ссылкам указывать на одно и то же представление (problem_list
) в urlpatterns
:
urlpatterns = [
# ⋮,
path('datalist/search/', views.problemlist, name='problem_list_search'),
path('datalist/<slug:category_slug>/', views.problemlist, name='problem_list_category'),
# ⋮
]
Затем в представлении мы смотрим, установлен ли параметр category_slug
, и если это не так, мы ищем часть строки запроса ?name=…
:
def problemlist(request, category_slug=None):
if category_slug is not None:
qs = DataModel.objects.get(category_slug=category_slug)
else:
DataModel.objects.filter(title__icontains=request.GET.get('name'))
return render(request,'list.html', {'qs':qs})
Представление на основе классов (CBV)
Вы также можете работать с представлением на основе классов, в этом случае вы можете определить подкласс ListView
с помощью:
from django.views.generic import ListView
class ProblemListView(ListView):
model = DataModel
template_name = 'list.html'
context_object_name = 'qs'
def get_queryset(self):
if 'category_slug' in self.kwargs:
return super().get_queryset().filter(
category_slug=self.kwargs['category_slug']
)
else:
return super().get_queryset().filter(
title__icontains=request.GET.get('name')
)
тогда мы снова создадим два пути, которые будут вызывать одно и то же представление:
urlpatterns = [
# ⋮,
path('datalist/search/', views.ProblemListView.as_view(), name='problem_list_search'),
path('datalist/<slug:category_slug>/', views.ProblemListView.as_view(), name='problem_list_category'),
# ⋮
]