Django ListView filter и orderby с пагинацией
Я создаю простой сайт электронной коммерции. Я использую ListView для представления главной страницы сайта, на которой отображаются товары. Я хочу иметь возможность фильтровать товары по их категориям и упорядочивать их по какому-либо фактору (например, по цене). По умолчанию он должен показывать все товары. И если есть другая страница с товарами данного вида, то она должна сохранять фильтр. Также буду очень признателен за объяснение.
.
Мой код:
views.py
from django.views.generic import ListView,
from .models import ShopItem
class HomeView(ListView):
model = ShopItem
paginate_by = 2
template_name = "home-page.html"
def get_queryset(self):
q = self.request.GET.get('filter', '')
if not q:
return self.model.objects.all()
return self.model.objects.filter(category=q)
models.py
from django.db import models
class ShopItem(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=100)
description = models.TextField()
category = models.CharField(max_length=15)
price = models.FloatField()
discount_price = models.FloatField(blank=True, null=True)
slug = models.SlugField()
home-page.html
<li class="nav-item active">
<a class="nav-link" href="/">All
<span class="sr-only">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Necklace</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Earrings</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Bracelets</a>
</li>
{% if is_paginated %}
<nav class="d-flex justify-content-center wow fadeIn">
<ul class="pagination pg-blue">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">«</span>
<span class="sr-only">Previous</span>
</a>
</li>
{% endif %}
{% for page in page_obj.paginator.page_range %}
{% if page_obj.number == page %}
<li class="page-item active">
<a class="page-link" href="?page={{ page }}">{{ page }}
<span class="sr-only">(current)</span>
</a>
</li>
{% else %}
<li class="page-item">
<a class="page-link" href="?page={{ page }}">{{ page }}
<span class="sr-only">{{ page }}</span>
</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}" aria-label="Next">
<span aria-hidden="true">»</span>
<span class="sr-only">Next</span>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
Конечно, это не работает. В вашем шаблоне жестко прописаны ссылки на страницы без фильтра.
<li class="page-item">
<a class="page-link" href="?page={{ page }}">
<-- href should be something like "?page={{ page }}&filter={{filter}}" -->
<-- or you can get filter from request "?page={{ page }}&filter={{request.GET.filter}}" -->
{{ page }}
<span class="sr-only">{{ page }}</span>
</a>
</li>
И, конечно, не забудьте добавить 'filter' в контексте, если вы используете переменную.
<!-- pagination from django-->
{% if is_paginated %}
<nav class="" aria-label="Page navigation">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li>
<a href="?page={{ page_obj.previous_page_number }}" class="btn btn-secondary btn-sm me-2">« PREV
</a>
</li>
{% endif %}
{% if page_obj.has_next %}
<li>
<a href="?page={{ page_obj.next_page_number }}" class="btn btn-secondary btn-sm"> NEXT »
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}