onskrer
@onskrer
начинающий Fullstack программист

Почему не работает пагинация?

пытаюсь настроить пагинацию, но почему-то не получается, подскажите что делаю не так? строго не судите, я еще новичок
views.py
class ProductList(ListView):
    model = Product
    template_name = 'products/list.html'
    paginate_by = 2
    context_object_name = "product_list"

def product_list(request, category_slug=None):
    category = None
    categories = Category.objects.all()
    products = Product.objects.filter(available=True)
    if category_slug:
        category = get_object_or_404(Category, slug=category_slug)
        products = products.filter(category=category)
    
    def get_context_data(self, **kwargs):
        context = super(ProductList(ListView), self).get_context_data(**kwargs)
        paginator = Paginator(products, self.paginate_by)

        page = self.request.GET.get('page')

        try:
            prods = paginator.page(page)
        except PageNotAnInteger:
            prods = paginator.page(1)
        except EmptyPage:
            prods = paginator.page(paginator.num_pages)

        context['prodsCatalog'] = prods
        return context

    return render(request,
                  'products/list.html',
                  {'category': category,
                   'categories': categories,
                   'products': products})


urls.py
urlpatterns = [
    url(r'^$', views.product_list, name='product_list'),
    url(r'^(?P<category_slug>[-\w]+)/$',
        views.product_list,
        name='product_list_by_category'),
    url(r'^(?P<id>\d+)/(?P<slug>[-\w]+)/$',
        views.product_detail,
        name='product_detail'),
]


paginator.html
<div class="pagination">
            <span class="page-links">
                {% if page_obj.has_previous %}
                    <a href="/products?page={{ page_obj.previous_page_number }}">previous</a>
                {% endif %}
                <span class="page-current">
                    Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
                </span>
                {% if page_obj.has_next %}
                    <a href="/products?page={{ page_obj.next_page_number }}">next</a>
                {% endif %}
            </span>
        </div>
  • Вопрос задан
  • 342 просмотра
Решения вопроса 1
vitaldmit
@vitaldmit
Веб программист
Попробуй так
def news(request):
    # 'Новости'
    all_news = News.objects.filter(type='news').filter(visible=True).order_by('-publish')
    paginator = Paginator(all_news, 10)
    page = request.GET.get('page')
    try:
        all_news = paginator.page(page)
    except PageNotAnInteger:
        # Если страница не является целым числом,возвращаем первую страницу.
        all_news = paginator.page(1)
    except EmptyPage:
        # Если номер страницы больше, чем общее количество страниц,
        # возвращаем последнюю.
        all_news = paginator.page(paginator.num_pages)
    return render(request, 'news.html',
                  {'page': page,
                   'all_news': all_news,})
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@Realmixer
Full stack Python (Django) web-developer
Присмотритесь к своему коду, это просто какая-тол дикая мешанина из CBV и процедурного подходов: функция product_list не входит в класс ProductList.
Ответ написан
neqrotek
@neqrotek
Тут написано, как правильно собрать пагинацию. Смысл в том, что сам список "Product" должен участвовать в переходе между страницами. А тут связи нет.
Как у меня получилось:
views.py
def product_list(request)
    category = None
    categories = Category.objects.all()
    products = Product.objects.filter(available=True)
    paginator = Paginator(products, 3)  # 12 posts in each page
    page = request.GET.get('page')

    if category_slug:
        category = get_object_or_404(Category, slug=category_slug)
        products = products.filter(category=category)
   
    try:
        products = paginator.page(page)
    except PageNotAnInteger:
        products = paginator.page(1)
    except EmptyPage:
        products = paginator.page(paginator.num_pages)

    return render(request,
                  'products/list.html',
                  {'category': category,
                   'categories': categories,
                   'products': products
                   'page', page})


В месте где будет выдаваться блок:

main.html
{% for product in products %}
{% endfor %}
{% include "shop/pagination.html" with page=products %}


И в шаблоне pagination.html:

pagination.html
<div class="pagination">
    <span class="step-links">
        {% if page.has_previous %}
            <a href="?page={{ products.previous_page_number }}">Назад</a>
        {% endif %}
        <span class="current">
            Страница {{ products.number }} из {{ products.paginator.num_pages }}.
        </span>
        {% if page.has_next %}
            <a href="?page={{ products.next_page_number }}">Вперед</a>
        {% endif %}
    </span>
</div>


Мое первое объяснение))
Виталий выше правильно написал, только чтобы понять, пришлось перелопатить документацию, по ссылке выше.

Чтобы работали страницы в категориях, надо все запихать в if

views.py
if category_slug:
        category = get_object_or_404(Category, slug=category_slug)
        products = products.filter(category=category)
        paginator = Paginator(products, 3)  # 12 posts in each page
        page = request.GET.get('page')

        try:
            products = paginator.page(page)
        except PageNotAnInteger:
            # If page is not an integer deliver the first page
            products = paginator.page(1)
        except EmptyPage:
            # If page is out of range deliver last page of results
            products = paginator.page(paginator.num_pages)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы