có cách nào để phân trang một rawqueryset bằng cách sử dụng phân vùng inbuilt của django không? khi tôi truyền nó vào một danh sách, nó ném một lỗi trong khuôn mặt của tôi ... TypeError: chuỗi dự kiến hoặc đối tượng Unicode, NoneType tìm thấy. Có cách nào để giái quyết vấn đề này không?django pagination và RawQuerySet
Trả lời
tôi quản lý để đạt được điều đó bằng cách sử dụng sau đây:
paginator = Paginator(files, 12)
paginator._count = len(list(files))
Mã trong django.core.paginator.py:
- kiểm tra cho dù _count được thiết lập
- nếu không thì cố gắng để chạy .count() không tồn tại
- nếu không thì hãy thử plain len
len trên raw_queryset không hoạt động nhưng chuyển đổi các đối tượng paginator thực tế vào một danh sách các công trình tìm cho tôi trong Django 1,3
Bạn có thể thiết lập các thuộc tính đếm bằng tay cho đối tượng RawQuerySet của bạn:
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
cho @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
django.core.paginator.Paginator tìm phương thức 'count()'. Vì vậy, thiết lập thuộc tính 'count' không hoạt động. – Rockallite
Tại sao bạn thử nghiệm nó? Tất nhiên, đó là một hack nhưng tôi đã sử dụng nó. Tôi có nghĩa là trong python bạn có thể thay thế một phương pháp khác. –
Rockallite, tôi đã thêm mã để minh họa cách thức hoạt động của hack này –
qs.filter(**pfilter).distinct().extra(select={'test': 'COALESCE(`psearch_program`.`eu_price`, 999999999)'}).extra(order_by=['test'])
-1: giải thích những gì đang được thực hiện, với khả năng tương thích với, v.v. –
- 1. Số Django RawQuerySet
- 2. Django lazy QuerySet và pagination
- 3. Oracle và Pagination
- 4. MySQL WHERE, LIMIT và pagination
- 5. jquery pagination
- 6. Oracle & Pagination
- 7. Mongoid pagination
- 8. pagination in jsf
- 9. C#: Pagination, Math.Ceiling
- 10. pagination trong play framework
- 11. Backbone JS Pagination
- 12. Lucene 4 Pagination
- 13. JSF, RichFaces, pagination
- 14. Plugin jQuery Pagination
- 15. Kohana 3 pagination
- 16. Tháng pagination với Kaminari
- 17. Codeigniter Pagination - Tôi stumped
- 18. Flask mongoengine pagination
- 19. Pagination sử dụng scrapy
- 20. Yii CGrid pagination và sắp xếp công việc doesnt CArrayDataProvider
- 21. SOA/Dịch vụ Web Pagination
- 22. Django-pagination có thể thực hiện nhiều lần truy cập trên mỗi trang không?
- 23. Giới hạn số trang pagination
- 24. JCR con thỏ rừng pagination
- 25. truy vấn SQL cho lưới asp.net pagination
- 26. Rails 3 pagination, will_paginate vs Kaminari
- 27. Pagination: Server Side hoặc Client Side?
- 28. Không tính đúng pagination vào trang JSF
- 29. Nhiều pagination với Kaminari qua Ajax
- 30. CakePHP Pagination để không làm việc
Rõ ràng len (danh sách (file)) là rất nhớ không hiệu quả cho các bộ truy vấn liệu lớn. Cho bạn biết truy vấn đã chạy, bạn có thể chạy truy vấn khác bằng COUNT (*) thay thế và gán truy vấn đó cho paginator._count miễn là số lượng kết quả sẽ không thay đổi giữa mỗi truy vấn. Cách khác DBMS có cách bạn có thể nhúng tổng số hàng trong mỗi hàng truy vấn nếu kết quả truy vấn liên tục thay đổi. – Chris
Thật không may, [RawQuerySet .__ getitem__()] (https://code.djangoproject.com/browser/django/trunk/django/db/models/query.py?rev=17381#L1517) danh sách cuộc gọi (tự) anyway - vì vậy nó sẽ được nạp hoàn toàn vào bộ nhớ ngay khi bạn gọi 'paginator.get_page()'. Để tránh điều đó, tôi nghĩ bạn phải phân lớp RawQuerySet và đảm bảo rằng SQL thô của bạn có LIMIT/OFFSET - và thậm chí sau đó, bạn sẽ mất bộ đệm kết quả của một queryset bình thường, vì vậy truy cập qs [0] hai lần sẽ nhấn DB hai lần. – AdamKG
Có nó sẽ nhấn hai lần. Tôi cũng mới khám phá ra nó. Vì vậy, tốt nhất bạn viết sql RẤT hiệu quả cho queryset thô đó và thay vì chuyển queryset thô sang len (list()) và để paginator bạn đầu tiên đánh giá queryset bằng cách lặp lại nó. Giống như l = [item cho item trong queryset] và sau đó truyền l cho cả paginator và len (l). Điều này cho phép bạn chỉ có một cuộc gọi cơ sở dữ liệu. –