【问题标题】:Django (2.0.4) Paginator get_page() not working properlyDjango (2.0.4) 分页器 get_page() 无法正常工作
【发布时间】:2018-04-10 13:28:49
【问题描述】:

我的问题出在 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(page) 仅适用于 1. 页。在第二页之后,它返回一个页面,其中包含一个带有空 QuerySet 的 object_list。

顺便说一句,可能这是一个基础知识。我只是想知道,这两个分配有什么区别:

选项 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 作为数据库后端。

奇怪的事情:如果我指定 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 %}

【问题讨论】:

    标签: python django pagination


    【解决方案1】:

    除非结果存回photo_list,否则第二行

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

    没有效果。这是您提供的两段代码之间的唯一区别(为了便于阅读,我建议使用基于filter 的第二段代码)。

    【讨论】:

    • 感谢您的承诺,我更喜欢album.photo_set.all() 选项,它更像是脚本而不是查询样式。更新了问题,如果您对我的问题有任何想法,我会很高兴。
    • 您能检查一下sayfa 的值吗?根据Paginator的源代码,如果提供的数字不是“有效”(不是整数或可以转换为整数的字符串,或者。 ..).
    • 我控制了 sayfapage 值。是的,如果它无效,它绝对会将值更改为 1。但问题仍然存在。我打算把db后端改成sqlite,非常怀疑djongo这个集成Django app和MondoDb的包。
    • 谢谢 Guybrush,因为我预计问题是关于 Djongo 包的,用解决方案部分更新了我的问题。
    【解决方案2】:

    这里:

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

    第二条语句在功能上是无操作的——对photo_list.filter(...) 的调用会创建一个新的QuerySet,它会立即被丢弃,因为您没有将它绑定到任何东西。

    因此,使用此代码,您传递给PaginatorQuerySet 实际上是Photo.objects.all()

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

    您也没有发布模板代码(嗯,相关部分...),所以我们不能确定没有其他问题,但根据您当前相册的照片数量,这可能只是预期的结果。提示:您可以使用photo_list.count() 来检查您应该为给定相册获取多少张照片(总计)。

    【讨论】:

    • 谢谢 bruno,你显然打开了我的思路 :) 我的问题还在继续,你能检查我的更新吗?
    猜你喜欢
    • 2018-11-05
    • 2018-10-27
    • 1970-01-01
    • 2013-12-14
    • 2014-09-21
    • 2013-08-22
    • 2012-09-25
    • 2016-07-29
    • 2017-11-27
    相关资源
    最近更新 更多