How to do it...

Follow these steps to execute the recipe:

  1. Our class-based view, MovieListView, will inherit the Django View class and override the get() method. If we needed to support it, we could also provide a post() method, which is used to distinguish requests via HTTP POST from those by GET:
# movies/views.py
from django.shortcuts import render
from django.core.paginator import (Paginator, EmptyPage,
PageNotAnInteger)
from django.views.generic import View

from .models import Genre, Director, Actor, Movie, RATING_CHOICES
from .forms import MovieFilterForm


class MovieListView(View):
form_class = MovieFilterForm
template_name = "movies/movie_list.html"
paginate_by = 15

def get(self, request, *args, **kwargs):
form = self.form_class(data=request.GET)
qs, facets = self.get_queryset_and_facets(form)
page = self.get_page(request, qs)
context = {
"form": form,
"facets": facets,
"object_list": page,
}
return render(request, self.template_name, context)
  1. We will also split up the remaining majority of the logic into separate methods get_queryset_and_facets(), filter_facets(), and get_page(), to make the class more modular:
# movies/views.py
# ...
class MovieListView(View):
# ...
def get_queryset_and_facets(self, form):
qs = Movie.objects.order_by("title")

facets = {
"selected": {},
"categories": {
"genres": Genre.objects.all(),
"directors": Director.objects.all(),
"actors": Actor.objects.all(),
"ratings": RATING_CHOICES,
},
}

if form.is_valid():
filters = (
("genre", "genres",),
("director", "directors",),
("actor", "actors",),
("rating", "rating",),
)
qs = self.filter_facets(facets, qs, form, filters)

return qs, facets

@staticmethod
def filter_facets(facets, qs, form, filters):
for facet, key in filters:
value = form.cleaned_data[facet]
if value:
selected_value = value
if facet == "rating":
rating = int(value)
selected_value = (rating,
dict(RATING_CHOICES)[rating])
facets["selected"][facet] = selected_value
filter_args = {key: value}
qs = qs.filter(**filter_args).distinct()
return qs

def get_page(self, request, qs):
paginator = Paginator(qs, PAGE_SIZE)
page_number = request.GET.get("page")
try:
page = paginator.page(page_number)
except PageNotAnInteger:
# If page is not an integer, show first page.
page = paginator.page(1)
except EmptyPage:
# If page is out of range,
# show last existing page.
page = paginator.page(paginator.num_pages)
return page
  1. We will need to create a URL rule in the URL configuration using the class-based view. You may have added a rule previously for the function-based movie_list view, which would have been similar. To include a class-based view in the URL rules, the as_view() method is used, as follows:
# movies/urls.py
from django.urls import path

from .views import MovieListView

urlpatterns = [
path('', MovieListView.as_view(), name="movie_list")
]
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.180.43