Как использовать одно и то же представление списка для поиска и набора запросов по категориям в django

Я пытаюсь построить функциональность в моем приложении Django, в котором мы можем получать данные двумя методами:

  1. Using Search
  2. 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'),
    # ⋮
]
Вернуться на верх