分页基于Django类的视图无法正常工作

时间:2018-09-01 09:13:18

标签: django python-3.x django-views django-class-based-views django-pagination

我正尝试在CBV中使用Django(v2.0)分页并出现问题。分页处于活动状态,因为标签{%if is_paginated%}返回“ True”并显示“ PagNav”,并且浏览器路径也发生了变化,例如(..?page = 1,...?page = 2等。 ..),但显示的元素全部,而不是我在“ paginate_by = 3”中设置的3。例如,如果查询有15个元素,则必须在每页显示3个元素,并且在下翻页中显示1到5个元素,但显示所有元素。我附上图片和代码:

enter image description here

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 %}

1 个答案:

答案 0 :(得分:2)

我认为问题的核心是您在模板中编写:

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

因此,您创建了一个project对象。但是,无论是否分页基于类的视图,都不会分页相关的对象管理器。您只能对object_list进行分页。

可能您可以通过以下方法解决它:

{% for album in object_list %}

此外,我认为您使基于类的视图变得极其复杂:这是Album上基于类的视图。是的,已过滤相册,但是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'])