在 Django 中使用两个以不同方式格式化的查询集进行分页
Posted
技术标签:
【中文标题】在 Django 中使用两个以不同方式格式化的查询集进行分页【英文标题】:Pagination in Django with two Querysets formatted in different ways 【发布时间】:2019-12-08 09:48:53 【问题描述】:我想让分页处理以不同方式格式化的两个单独的查询集。第一个查询集较小,永远不会比第一页长。第二个查询集很长,会持续 5 或 6 页。两个查询集的结果内容是一样的,但是我在html模板中的格式不同。
Book 和 PremiumBook 的模型完全相同,只是 PremiumBook 的书籍更多(并且包含 Book 中的所有元素)。
我将包含 views.py 和模板:
def servicesListView(request, category):
model = Books
table = Books.objects.filter(category=category)
values_books = table.filter().values_list("serviceid")
# remove these observations from next table. My next table is premium and not available to non-authenticated users
new_table = PremiumBooks.objects.filter(category=category).exclude(bookid__in=values_books)
new_table = new_table.filter().annotate(price_count=Count('premiumcost__price')).order_by('-price_count')[:60]
page = request.GET.get('page', 1)
paginator = Paginator(new_table, 5)
try:
new_table = paginator.page(new_table)
except PageNotAnInteger:
new_table = paginator.page(1)
except EmptyPage:
new_table = paginator.page(paginator.num_pages)
return render(request, 'services/index.html', 'table': table, 'new_table': new_table)
那么,这是他们的模板:
<main class="ui-book-list">
<div class="results-list grid-view">
<div class="container">
<h2>Book list </h2>
<div class="grid-results-list book-list">
% for book in table %
<div class="record">
<div class="content">
<h6>
book.easy_desc
</h6>
<div class="group">
<div class="category">
<span>Category:</span> book.category
</div>
<span class="divider"></span>
<div class="code">
<span>Barcode:</span> book.code
</div>
</div>
</div>
</div>
</a>
% empty %
% endfor %
% for book in new_table %
<div class="premium-user">
<div class="record">
<div class="content">
<div class="premium-tag" onclick="openPremiumModal()"><i class="fas fa-lock"></i>Premium User</div>
<a class="link" onclick="openPremiumModal()">
<h6>
book.desc_us
</h6>
</a>
<div class="group">
<div class="category ">
<span class="">Category:</span> book.category
</div>
<span class="divider"></span>
<div class="code ">
<span class="">Barcode:</span> book.code
</div>
</div>
</div>
</div>
</div>
% endfor %
#this is my pagination stuff for one table, not sure how to do it for combined table
% if new_table.has_other_pages %
<ul class="pagination mt-5 pagination-sm justify-content-center">
% if new_table.has_previous %
<li class="page-item">
<a
class="page-link"
href="?page= new_table.previous_page_number % if request.GET.csrfmiddlewaretoken %&csrfmiddlewaretoken= request.GET.csrfmiddlewaretoken % endif %% if request.GET.s %&s= request.GET.s % endif %">
<i class="fa fa-chevron-left" aria-hidden="true"></i>
</a>
</li>
% else %
<li class="page-item disabled">
<span class="page-link">
<i class="fa fa-chevron-left" aria-hidden="true"></i>
</span>
</li>
% endif %
% if new_table.number|add:'-4' > 1 %
<li class="page-item">
<a class="page-link" href="?page= new_table.number|add:'-5' % if request.GET.csrfmiddlewaretoken %&csrfmiddlewaretoken= request.GET.csrfmiddlewaretoken % endif %% if request.GET.s %&s= request.GET.s % endif %">…</a>
</li>
% endif %
% for i in new_table.paginator.page_range %
% if new_table.number == i %
<li class="page-item active">
<span class="page-link"> i <span class="sr-only">(current)</span></span>
</li>
% elif i > new_table.number|add:'-5' and i < new_table.number|add:'5' %
<li class="page-item">
<a class="page-link" href="?page= i % if request.GET.csrfmiddlewaretoken %&csrfmiddlewaretoken= request.GET.csrfmiddlewaretoken % endif %% if request.GET.s %&s= request.GET.s % endif %"> i </a>
</li>
% endif %
% endfor %
% if new_table.paginator.num_pages > new_table.number|add:'4' %
<li class="page-item">
<a class="page-link" href="?page= new_table.number|add:'5' % if request.GET.csrfmiddlewaretoken %&csrfmiddlewaretoken= request.GET.csrfmiddlewaretoken % endif %% if request.GET.s %&s= request.GET.s % endif %">…</a>
</li>
% endif %
% if new_table.has_next %
<li class="page-item">
<a class="page-link" href="?page= new_table.next_page_number % if request.GET.csrfmiddlewaretoken %&csrfmiddlewaretoken= request.GET.csrfmiddlewaretoken % endif %% if request.GET.s %&s= request.GET.s % endif %">
<i class="fa fa-chevron-right" aria-hidden="true"></i>
</a>
</li>
% else %
<li class="page-item disabled">
<span class="page-link"><i class="fa fa-chevron-right" aria-hidden="true"></i></span>
</li>
% endif %
</ul>
% endif %
</div>
</div>
</div>
</main>
【问题讨论】:
您能具体说明您希望发生的事情吗? 您想要在您的页面上选择非高级图书列表,但又想为高级图书分页? 我想先列出基础书籍,然后是高级书籍。高级书籍将对其进行锁定,并且只有登录的用户才能访问高级书籍。它将采用不同的格式,因为高级书籍将锁定它们并重定向到登录页面。 拥有一个具有premium
布尔列的Book
模型不是更容易吗?然后在您的列表视图中,您只需按匹配类别过滤书籍
渲染书籍时,如果它们是优质书籍,则添加逻辑以“锁定”它们
【参考方案1】:
你可以有 2 个不同的QuerySets
,甚至可以像这样按不同的数量分页
regular_books_query = Books.objects.filter(category=category) # plus whatever
premium_books_query = Premium.objects.filter(category=category) # plus whatever
regular_paginator = Paginator(regular_books, 10)
premium_paginator = Paginator(premium_books, 5)
page = request.GET.get('page')
regular_books = regular_paginator.get_page(page)
premium_books = premium_paginator.get_page(page)
return render('template.html',
'regular_books': regular_books,
'premium_books': premium_books
)
Now whenever you go to the next page you will get the next page in both queryset
【讨论】:
以上是关于在 Django 中使用两个以不同方式格式化的查询集进行分页的主要内容,如果未能解决你的问题,请参考以下文章
在不同的占位符/模板上以不同的方式呈现 Django-CMS 插件
Django:使用 ajax 查询(字符串/Json)时出现格式问题