Python django分页和RawQuerySet
有没有一种方法可以使用django内置的分页来分页rawqueryset?Python django分页和RawQuerySet,python,django,django-pagination,Python,Django,Django Pagination,有没有一种方法可以使用django内置的分页来分页rawqueryset? 当我将其转换为列表时,它会在我面前抛出一个错误…TypeError:预期的字符串或Unicode对象,未找到NoneType。有办法解决这个问题吗?我通过以下方法实现了这一目标: paginator = Paginator(files, 12) paginator._count = len(list(files)) django.core.paginator.py中的代码: 检查是否设置了_计数 如果不存在,则尝试运
当我将其转换为列表时,它会在我面前抛出一个错误…TypeError:预期的字符串或Unicode对象,未找到NoneType。有办法解决这个问题吗?我通过以下方法实现了这一目标:
paginator = Paginator(files, 12)
paginator._count = len(list(files))
django.core.paginator.py中的代码:
- 检查是否设置了_计数
- 如果不存在,则尝试运行不存在的.count()
- 如果不是,则尝试普通len
raw_queryset上的len不起作用,但将实际paginator对象转换为列表可以在Django 1.3中为我找到。您可以手动设置RawQuerySet对象的属性计数:
items = Item.objects.raw("select * from appitem_item")
def items_count():
cursor = connection.cursor()
cursor.execute("select count(*) from appitem_item")
row = cursor.fetchone()
return row[0]
items.count = items_count
对于@Rockallite
>>> class A():
... def b(self):
... print 'from b'
...
>>>
>>> (A()).b()
from b
>>> def c():
... print 'from c'
...
>>> a = A()
>>> a.b = c
>>> a.b()
from c
显然,对于大型原始查询集,len(list(files))的内存效率非常低。如果您知道所运行的查询,您可以使用COUNT(*)运行另一个查询,并将其分配给分页器。\u COUNT,只要每个查询之间的结果数不会改变。或者,如果查询结果不断变化,不同的DBMS有不同的方法可以在查询的每一行中嵌入总行数。不幸的是,无论如何都要调用list(self)——因此只要调用
paginator.get_page()
,它就会被完全加载到内存中。为了避免这种情况,我认为您必须将RawQuerySet子类化,并确保您的原始SQL具有LIMIT/OFFSET,即使这样,您也将丢失普通queryset的结果缓存,因此访问qs[0]两次将对DB造成两次影响。是的,它会造成两次影响。我也是为自己发现的。因此,最好为该原始查询集编写非常高效的sql,而不是将原始查询集传递给len(list())和paginator,而是首先通过循环对查询集进行求值。比如l=[item for item in queryset],然后将该l传递给paginator和len(l)。这只提供一个数据库调用。django.core.paginator.paginator查找count()
方法。所以设置count
属性不起作用。为什么,您测试了它?当然,这是一个黑客,但我用了它。我的意思是,在python中,你可以用另一个方法替换一个方法。Rockallite,我添加代码是为了说明这种黑客是如何工作的——1:解释正在做什么,与什么兼容,等等。
qs.filter(**pfilter).distinct().extra(select={'test': 'COALESCE(`psearch_program`.`eu_price`, 999999999)'}).extra(order_by=['test'])