首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >`order_by`调用后Django Paginate中的重复元素

问`order_by`调用后Django Paginate中的重复元素
EN

Stack Overflow用户
提问于 2015-07-31 01:27:18
回答 2查看 4K关注 0票数 15

我用的是Django 1.7.7

我想知道有没有人经历过这种事。这是我的疑问:

代码语言:javascript
复制
events = Event.objects.filter(
    Q(date__gt=my_date) | Q(date__isnull=True)
).filter(type__in=[...]).order_by('date')

当我试图将它分页时

代码语言:javascript
复制
p = Paginator(events, 10)
p.count  # Gives 91

event_ids = []
for i in xrange(1, p.count / 10 + 2):
    event_ids += [i.id for i in p.page(i)]

print len(event_ids)  # Still 91
print len(set(event_ids))  # 75

我注意到,如果我删除了.order_by,我就不会得到任何副本。然后,我尝试了.order_by和Event.objects.all().order_by('date'),它没有提供副本。

最后,我尝试了这个:

代码语言:javascript
复制
events = Event.objects.filter(
    Q(date__gt=my_date) | Q(date__isnull=True)
).order_by('date')

p = Paginator(events, 10)
events.count()  # Gives 131
p.count  # Gives 131

event_ids = []
for i in xrange(1, p.count / 10 + 2):
    event_ids += [i.id for i in p.page(i)]

len(event_ids)  # Gives 131
len(set(event_ids))  # Gives 118

..。也有重复的。有人能解释一下这是怎么回事吗?

我深入研究了Django源代码(https://github.com/django/django/blob/master/django/core/paginator.py#L46-L55),这似乎与Django如何分割object_list有关。

任何帮助都是非常感谢的。谢谢。

编辑:distinct()对副本没有影响。数据库中没有任何副本,而且我认为查询不会引入任何副本([e for e in events.iterator()]不会产生任何副本)。就在分页器被切割的时候。

Edit2:下面是一个更完整的例子

代码语言:javascript
复制
In [1]: from django.core.paginator import Paginator

In [2]: from datetime import datetime, timedelta

In [3]: my_date = timezone.now()

In [4]:   1 events = Event.objects.filter(
          2     Q(date__gt=my_date) | Q(date__isnull=True)
          3 ).order_by('date')

In [5]: events.count()
Out[5]: 134

In [6]: p = Paginator(events, 10)

In [7]: p.count
Out[7]: 134

In [8]: event_ids = []

In [9]:   1 for i in xrange(1, p.num_pages + 1):
          2     event_ids += [j.id for j in p.page(i)]

In [10]: len(event_ids)
Out[10]: 134

In [11]: len(set(event_ids))
Out[11]: 115
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-04 05:24:43

哦,在黑暗中开枪,但我想我可能知道它是什么。我无法在sqlite中复制它,但使用mysql。我认为mysql试图对具有相同值的列进行排序时,它在切片时返回了相同的结果。

分页拼接基本上是执行SELECT ... FROM ... WHERE (date > D OR date IS NULL) ORDER BY date ASC LIMIT X OFFSET X的sql语句。

但是,当date为null时,我不确定mysql是如何排序的。因此,当我尝试使用极限10和限制10偏移量10的两个sql查询时,它返回具有相同行的集合,而极限20则生成唯一的集合。

您可以尝试将您的order_by更新为order_by('id','date'),让它首先按照唯一的字段排序,它可能会修复它。

票数 23
EN

Stack Overflow用户

发布于 2018-09-27 13:26:51

在将.distinct()传递给Paginator之前,尝试在查询中使用它。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31736700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档