Представление на основе класса Django с разбиением на страницы не работает должным образом

Я пытаюсь использовать разбиение на страницы Django (v2.0) с CBV и получаю проблемы. Разбивка на страницы активна, потому что тег {% if is_paginated %} возвращает «True» и показывает «PagNav», а также изменения пути браузера, например (..?page=1, ...?page=2 и т. д. ..), но отображаются все элементы, а не 3, как я установил в "paginate_by=3". Например, если в запросе 15 элементов, должно отображаться 3 элемента на странице и от 1 до 5 в разбиении на страницы ниже, но отображаются все элементы. Прикрепляю изображение и код:

введите здесь описание изображения

models.py:

from django.db import models
from django.contrib.auth.models import User
from ckeditor.fields import RichTextField

# Create your models here.

class Project(models.Model):
    user = models.ForeignKey(User, on_delete = models.CASCADE, default=1)
    name = models.CharField(verbose_name='Nombre del proyecto', max_length=200)
    client = models.CharField(verbose_name='Nombre del cliente', max_length=200)
    description = RichTextField(verbose_name='Descripción')
    start = models.DateField(verbose_name='Fecha de Inicio', null=True, blank=True)
    ending = models.DateField(verbose_name='Fecha de Finalización', null=True, blank=True)
    order = models.SmallIntegerField(verbose_name="Orden", default=0)
    created = models.DateTimeField(verbose_name='Fecha de creación', auto_now_add=True)
    updated = models.DateTimeField(verbose_name='Fecha de modificación', auto_now=True)

    class Meta:
        verbose_name = 'Proyecto'
        verbose_name_plural = 'Proyectos'
        ordering = ['-start', 'order']

    def __str__(self):
        return self.name

class Album(models.Model):
    project = models.ForeignKey(Project, verbose_name='Proyecto relacionado', on_delete = models.CASCADE)
    title = models.CharField(verbose_name='Título de la imagen', max_length=200)
    image = models.ImageField(verbose_name='Imagen', upload_to='portfolio')
    created = models.DateTimeField(verbose_name='Fecha de creación', auto_now_add=True)
    updated = models.DateTimeField(verbose_name='Fecha de modificación', auto_now=True)

    class Meta:
        verbose_name = 'Imagen en el album'
        verbose_name_plural = 'Imágenes en el album'
        ordering = ['created']

        def __str__(self):
            return self.title

views.py:

@method_decorator(staff_member_required(login_url='login'), name='dispatch')
class AlbumListView(SingleObjectMixin, ListView):

    paginate_by = 3
    template_name = "core/album_list_form.html"


    def get(self, request, *args, **kwargs):
        self.object = self.get_object(queryset=Project.objects.all())
        return super().get(request, *args, **kwargs)


    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['project'] = self.object
        return context


    def get_queryset(self):
        return self.object.album_set.all()


@method_decorator(staff_member_required(login_url='login'), name='dispatch')
class ProjectUpdateView(UpdateView):

    model = Project
    template_name = "core/project_update_form.html"
    form_class = ProjectUpdateForm


    def get_success_url(self):
        return  reverse_lazy('portfolio_update', args=[self.object.id]) + '?ok'

urls.py:

from django.urls import path
from . import views

from .views import *

urlpatterns = [
    path('', HomePageView.as_view(), name="home"),
    path('album/list/<int:pk>', AlbumListView.as_view(), name="portfolio_list_album"),
    # Update Views
    path('project/update/<int:pk>', ProjectUpdateView.as_view(), name="portfolio_update"),
    .
    .
    .

album_list_form.html:

{% extends "core/base.1.html" %}
{% load static %}
{% block title %}Imágenes de {{project.name}}{% endblock %}

{% block content %}

    <div class="container">
        <div class="row mt-5 mb-2 ml-1">
            <div class="mt-3">
                <h2 class="mt-5 mb-0"><a style="color: #343a40;" href="{% url 'portfolio_update' project.id %}">{{project.name}}</a></h2>
                <div class="subheading mb-5">Imágenes:</div>
            </div>
        </div>
    </div>


    <div class="album py-5 bg-light">
        <div class="container" style="margin-bottom: 2.5rem!important; margin-top: 2.5rem!important;">
            <div class="row">

                {% for album in project.album_set.all %}          

                        <div class="col-md-4">
                            <div class="card mb-4 shadow-sm">
                            <img class="card-img-top border-bottom p-2 p-2 p-2 p-2 bg-light" src="{{album.image.url}}" alt="Card image cap">
                            <div class="card-body">
                                <p class="card-text" title="{{album.title}}" style="color: #343a40;"><strong>{{album.title|truncatechars:31}}</strong></p>
                                <div class="d-flex justify-content-between align-items-center">
                                <div class="btn-group">
                                    <button type="button" class="btn btn-sm btn-outline-warning"><i class="fa fa fa-pencil"></i></button>
                                    <button type="button" class="btn btn-sm btn-outline-danger"><i class="fa fa fa-times"></i></button>    
                                </div>
                                <p></p>

                                </div>
                                <small class="text-muted">Última modificación: {{album.updated|date:"SHORT_DATE_FORMAT"}} {{album.updated|time:"h:i a"}}</small>
                            </div>
                            </div>
                        </div>           

                {% endfor %}
            </div>


        </div>

            {% if is_paginated %}

                <nav aria-label="Page navigation example">
                    <ul class="pagination pagination-lg justify-content-center">

                        {% if page_obj.has_previous %}
                            <li class="page-item">
                                <a class="page-link" style="color:#bd5d38;" href="?page={{ page_obj.previous_page_number }}" aria-label="Previous">
                                    <span aria-hidden="true">&laquo;</span>
                                    <span class="sr-only">Previous</span>
                                </a>
                            </li>
                        {% endif %}

                        {% for i in paginator.page_range %}
                            {% if page_obj.number == i %}
                                <li class="page-item"><a class="page-link" style="color:#ffffff; background-color: #343a40;" href="?page={{ i }}">{{ i }}</a></li>
                            {% else %}
                                <li class="page-item"><a class="page-link" style="color:#bd5d38;" href="?page={{ i }}">{{ i }}</a></li>
                            {% endif %}
                        {% endfor %}

                        {% if page_obj.has_next %}
                            <li class="page-item">
                                <a class="page-link" style="color:#bd5d38;" href="?page={{ page_obj.next_page_number }}" aria-label="Next">
                                <span aria-hidden="true">&raquo;</span>
                                <span class="sr-only">Next</span>
                                </a>
                            </li>
                        {% endif %}

                    </ul>
                </nav>

            {% endif %}

    </div>

{% endblock %}

person nilsoviani    schedule 01.09.2018    source источник
comment
Но вы не разбиваете на страницы album, вы разбиваете на страницы Project. Разбивая набор запросов на страницы, вы не разбиваете на страницы связанные объекты.   -  person Willem Van Onsem    schedule 01.09.2018
comment
Быстрое решение может состоять в том, чтобы заменить {% for album in project.album_set.all %} на {% for album in object_list %}. На самом деле это одна из веских причин, почему вы не должны не писать запросы в шаблоне. Кроме того, это выглядит довольно грубо.   -  person Willem Van Onsem    schedule 01.09.2018


Ответы (1)


Я думаю, что суть проблемы в том, что вы пишете в шаблоне:

{% for album in project.album_set.all %}

Таким образом, вы создаете объект project. Но независимо от того, разбиваете ли вы свое представление на основе классов, вы не будете разбивать на страницы связанный диспетчер объектов. Вы только разбиваете на страницы object_list.

Вероятно, вы можете решить это с помощью:

{% for album in object_list %}

Кроме того, я думаю, что вы делаете представление на основе классов чрезвычайно сложным: это представление на основе классов над Albums. Да, альбомы отфильтрованы, но Album должен быть здесь центральным. Я думаю, что это можно переписать так:

from django.urls import path
from . import views

from .views import *

urlpatterns = [
  path('', HomePageView.as_view(), name="home"),
  path('album/list/<int:project_pk>', AlbumListView.as_view(), name="portfolio_list_album"),
  path('project/update/<int:pk>', ProjectUpdateView.as_view(), name="portfolio_update"),
]

Затем в самом представлении:

@method_decorator(staff_member_required(login_url='login'), name='dispatch')
class AlbumListView(ListView):

    model = Album
    paginate_by = 3
    template_name = "core/album_list_form.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['project'] = Project.objects.get(pk=self.kwargs['project_pk'])
        return context

    def get_queryset(self):
        return Album.objects.filter(project_id=self.kwargs['project_pk'])
person Willem Van Onsem    schedule 01.09.2018
comment
Большое спасибо! {% для альбома в object_list %} было решением, я переписывал шаблон, пробовал много решений и не видел этого. Пойду последовать совету, попробую! - person nilsoviani; 01.09.2018
comment
project_pk в get_context_data не распознается как объявленная переменная - person nilsoviani; 01.09.2018
comment
@nilsoviani: помогает ли доступ к нему через self.kwargs? - person Willem Van Onsem; 01.09.2018
comment
AttributeError at /album/list/2 Объект «AlbumListView» не имеет атрибута «объект». Метод запроса: GET URL запроса: 127.0.0.1:8000/album/list/2 Версия Django: 2.0.2 Тип исключения: AttributeError Значение исключения: объект "AlbumListView" не имеет атрибута "объект" - person nilsoviani; 01.09.2018
comment
@nilsoviani: Я думаю, это из-за SingleObjectMixin, что не имеет смысла. Вы можете сказать, что SingleObjectMixin является противоположностью ListView. Наверное поможет удаление. - person Willem Van Onsem; 01.09.2018
comment
Да, еще раз спасибо! Это было так. Работает правильно. Я видел эту информацию о нумерации страниц с помощью CBV здесь - person nilsoviani; 01.09.2018