Django(2.0.4)Paginator get_page()无法正常工作

时间:2018-04-10 13:28:50

标签: python django pagination

我的问题是Paginator get_page()方法令人兴奋。这是我的观看代码:

@login_required
def photo_index_default_album(request):
album = Album.get_default_album(request.user)

photo_list = album.photo_set.all()

paginator = Paginator(photo_list, 2)  # Show 2 photo per page
page = request.GET.get('sayfa')
photos = paginator.get_page(page)

context = {
    'title': album.name,
    'photo': photos,
}

return render(request, 'photo/index.html', context)

paginator.get_page(页面)仅适用于1.页面。在第二页之后,它返回一个页面,该页面具有一个带有空QuerySet的object_list。

顺便说一下,这可能是一个基本知识。我只是想知道,这2个分配之间有什么区别:

选项1:

photo_list = Photo.objects.all()
photo_list.filter(Q(album=album.id))

选项2:

photo_list = Photo.objects.filter(album=album.id)

更新 好的,我理解2个选项之间的区别。但我的问题仍在继续。我根据您的有用答案更新了上面的代码以供查询。

问题:这个分页仅适用于1.分页。如果' sayfa'页面值的变量变得不同于1,它不起作用。在这种情况下,paginator.get_page()返回一个页面,该页面具有一个带有空QuerySet的object_list。检查photo_list.count()页面,它们在每次调用时都是正确的。此外,模板中的分页器变量对于第一页和最后一页也是如此。但我没有显示空图像的原因。为什么paginator.get_page(page)返回一个具有空QuerySet的object_list,而分页不同于1?顺便说一句,我使用MongoDB作为db后端。

奇怪的事情:如果我指定photo_list = Photo.objects.all(),我的模板正在按预期工作。但是我想只展示一张特定的专辑'相片。 最终更新说明:由于有很多图片,我没有注意到这个问题,但也有错误。

最终更新:(解决方案) 查询结果错误的原因是关于Djongo包的LIMIT-OFFSET查询的错误。我打开了一个问题https://github.com/nesdis/djongo/issues/106

我的模特:

class Photo(models.Model):
image = models.ImageField()
album = models.ManyToManyField(Album)

class Album(models.Model):
name = models.CharField(max_length=150)
user = models.ForeignKey('accounts.MyUser', verbose_name='Album Owner', on_delete=models.CASCADE)

我的模板:抱歉给您带来不便,有点长......

{% extends 'base.html' %}

{% block title %}
{{ block.super }} - {{ title }}
{% endblock %}

{% block body %}
<div class="container">
    {% for pht in photo %}
        <div class="row justify-content-center" style="margin-bottom: 30px">
            <div class="col-md-6">
                <div class="card">
                    {% if pht.image %}
                        <img class="card-img-top img-fluid" src="{{ pht.image.url }}" alt="Card image cap">
                    {% endif %}
                    <div class="card-body">
                        <h5 class="card-title">{{ title }}
                            <small style="color: #4e555b"> {{ pht.upload_date|timesince }} before</small>
                        </h5>
                        {% if request.user.is_authenticated %}
                            <a href="{{ pht.get_delete_url }}" class="btn btn-danger">Delete</a>
                        {% endif %}
                    </div>
                </div>
            </div>
        </div>
    {% endfor %}

    <div class="row justify-content-center" style="margin-bottom: 30px">
        <div class="col-md-6">
            <div class="pagination">
        <span class="step-links">
            {% if photo.has_previous %}
                <a href="?sayfa=1{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">&laquo; first</a>
                <a href="?sayfa={{ photo.previous_page_number }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">previous</a>
            {% endif %}

            <span class="current">
                Page {{ photo.number }} of {{ photo.paginator.num_pages }}.
            </span>

            {% if photo.has_next %}
                <a href="?sayfa={{ photo.next_page_number }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">next</a>
                <a href="?sayfa={{ photo.paginator.num_pages }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">last &raquo;</a>
            {% endif %}
        </span>
            </div>
        </div>
    </div>

</div>

{% endblock %}

2 个答案:

答案 0 :(得分:2)

除非结果存储在photo_list

的第二行
photo_list = Photo.objects.all()
photo_list.filter(Q(album=album.id))

无效。这是您提供的两段代码之间的唯一区别(我建议使用第二段代码,基于filter,以提高可读性)。

答案 1 :(得分:1)

下面:

photo_list = Photo.objects.all()
photo_list.filter(Q(album=album.id))

第二个声明在功能上是一个无操作 - 对photo_list.filter(...)的调用会创建一个新的QuerySet,由于您不将其绑定到任何内容,因此立即将其丢弃。

因此,使用此代码,您传递给QuerySet的{​​{1}}确实是Paginator

在第二种情况下,您将Photo.objects.all()重新绑定到photo_list的结果(这只是写Photo.objects.filter(album=album.id)的最短方式,因此您只需获取整个表格内容与当前相册匹配的行。您没有发布整个模型,但您也可以使用相关描述符获得相同的结果(默认情况下,这将是Photo.objects.filter(Q(album=album.id)),参见精细手册)。所以您的查询集确实会有更少的行。

您没有发布模板代码(以及......的相关部分),因此我们无法确定是否存在其他问题,但这取决于您当前的专辑和&n #39;照片计数这可能只是预期的结果。提示:您可以使用album.photo_set.all()查看给定相册应获得的照片总数(总计)。