class CatList(ListView):
model = Cat
# Only return the cats for the logged in user
def get_queryset(self):
# Note how the logged in user is being accessed
return Cat.objects.filter(user=self.request.user)
👀 The
request
object is accessible viaself.request
in all overridden methods.
class CatList(ListView):
model = Cat
def get_context_data(self, **kwargs):
# Call the base implementation first to get the context dict
context = super().get_context_data(**kwargs)
# Example: Pass the 'sort' query param (or empty string if not existing) sent in the request
context['sort'] = self.request.GET.get('sort', '')
return context
All CBVs can access the pk
URL parameter using self.kwargs['pk']
in any method being overridden.
If the following syntax is not flexible enough:
class DeleteFeeding(DeleteView):
model = Feeding
# This syntax allows for dynamic interpolation of
# the attributes on the deleted object!
success_url = '/cats/{cat_id}'
you can also override the get_success_url
method:
class DeleteReview(DeleteView):
model = Review
def get_success_url(self):
# Assuming the review belongs to a recipe
return f"/recipes/{self.object.recipe.id}"
👀 Note that the object being accessed in a DetailView, DeleteView, CreateView or UpdateView is accessed via
self.object
.
class CatCreate(CreateView):
model = Cat
fields = ['name', 'breed', 'description', 'age']
success_url = '/cats'
def form_valid(self, form):
# form.instance is the new, but unsaved object
form.instance.user = self.request.user
# Let CreateView's form_valid method do its thing
return super().form_valid(form)
class CatDelete(LoginRequiredMixin, DeleteView):
model = Cat
success_url = '/cats'
def dispatch(self, request, *args, **kwargs):
cat = self.get_object()
if cat.user != request.user:
# Not owner - do redirect instead of letting DeleteView do its job
return redirect('index')
return super().dispatch(request, *args, **kwargs)
Query parameters (key=value pairs after the ? in the url) do not impact routing - continue to use the "List/Index" functionality.
Example:
SORT BY: <a href="{% url cats_list %}?sort=name">Name</a> | <a href="{% url cats_list %}?sort=breed">Breed</a>
Access query params in the view function on the request.GET
QueryDict:
# sort will be 'name', 'breed', or None
sort = request.GET.get('sort')
If there's a query param, use order_by
to sort the QuerySet:
if sort:
cats = Cat.objects.order_by(sort)
else:
cats = Cat.objects.all()
# Or maybe provide a default...
# cats = Cat.objects.order_by('name')
If using a ListView
, override the get_queryset()
method:
class CatList(ListView):
model = Cat
def get_queryset(self):
sort = self.request.GET.get('sort', '')
if sort:
return Cat.objects.order_by(sort)
else:
return Cat.objects.all()