开发环境:
python 3.8.6 django 3.1.7
场景:
经常有从数据库中获取一批数据,然后在前端以列表的形式展现,比如:获取到所有的用户,然后在用户列表页面展示。
常规写法是,我们通过Django的ORM查询到所有的数据,然后展示出来,代码如下:
def user_list(request):
"""返回UserProfile中所有的用户"""
users = UserProfile.objects.all()
return render(request, 'talks/users_list.html', context={"user_list": users})
这样能够解决问题,但是Django针对这种常用场景,提供了一个更快速便捷的方式,那就是ListView
,用法如下:
from django.views.generic import ListView
class UsersView(ListView):
model = UserProfile
template_name = 'talks/users_list.html'
context_object_name = 'user_list'
如果需要对数据做过滤,ListView
实现可以重写get_queryset函数方法实现,代码如下:
from django.views.generic import ListView
class UsersView(ListView):
model = UserProfile
template_name = 'talks/users_list.html'
context_object_name = 'user_list'
def get_queryset(self):
""" 重写get_queryset()方法实现筛选排序,效果get_queryset()>queryset>model """
sort = self.kwargs.get('sort')
return Article.objects.all().order_by('-is_top', '-create_date')
如果想要返回给Template的数据需要多个,不仅仅是user_list
,可能还有其他数据,如获取当前登陆用户的详细信息,就需要用到重写get_context_data方法,代码如下:
from django.views.generic import ListView
class UsersView(ListView):
model = UserProfile
template_name = 'talks/users_list.html'
context_object_name = 'user_list'
def get_context_data(self, **kwargs): # 重写get_context_data方法
# 很关键,必须把原方法的结果拿到
context = super().get_context_data(**kwargs)
username = self.request.GET.get('user', None)
context['user'] = UserProfile.objects.get(username=username
return context
这样,你返回给Template页面时,get_context_data() 向template传递更多信息,模板可以直接用{{user}} 来调用。
接下来做前端页面的分页展示,完整步骤:
- 应用views.py中用以下代码
from datetime import datetime
from django.shortcuts import render
from django.views.generic import ListView
from apps.blog import settings
from apps.blog.models import Article
from apps.blog.utils.blog import getPages
# blog首页列表
class blogIndexListView(ListView):
""" 模板,标签名,分页:::template_name,context_object_name,paginate_by 都是固定名称不要更改 """
template_name = 'blog/blog1.html'
context_object_name = 'articles'
paginate_by = getattr(settings, 'BASE_PAGE_BY', None)
paginate_orphans = getattr(settings, 'BASE_ORPHANS', 0)
http_method_names = ['GET', 'get'] # 加上这一行,告知允许那种请求方式
# """ 排序 """
# model = Article
#
# def get_ordering(self):
# sort = self.kwargs.get('sort')
# if sort == 'v':
# return '-views', '-update_date', '-id'
# return '-is_top', '-create_date'
# """ 排序 """
def get_queryset(self):
""" 重写get_queryset()方法实现筛选排序,效果get_queryset()>queryset>model """
sort = self.kwargs.get('sort')
if sort == 'v':
article = Article.objects.all().order_by('-views', '-update_date', '-id')
return article
return Article.objects.all().order_by('-is_top', '-create_date')
def get_context_data(self, **kwargs):
""" get_context_data() 向template传递更多信息,模板可以直接用{{now}} """
context = super(blogIndexListView, self).get_context_data(**kwargs)
context['now'] = datetime.now()
paginator = context.get('paginator')
page = context.get('page_obj')
pages = getPages(paginator, page)
context['pages'] = pages
return context
paginate_by 是每页个数,可设置为具体值,我是写到settings中了。get_context_data为context上下文对象增加额外数据
- 2. 创建utils.py文件,代码如下:
def getPages(paginator, page):
""" 这部分是为了再有大量数据时,仍然保证所显示的页码数量不超过5 """
if page.number < 3:
if paginator.num_pages <= 5:
pages = range(1, paginator.num_pages + 1)
else:
pages = range(1, 6)
elif (page.number >= 3) and (page.number <= paginator.num_pages - 2):
pages = range(page.number - 2, page.number + 3)
else:
pages = range(paginator.num_pages - 3, paginator.num_pages + 1)
return pages
- 3. 对应的模板文件blog.html中,代码如下:
<div class="pagination">
<ul>
{% if page_obj.has_previous %}
<li>
<a href="{% url 'blog:blog_home1' %}?page={{ page_obj.previous_page_number }}">上一页</a>
</li>
{% else %}
<li class="disabled"><a href="#">上一页</a></li>
{% endif %}
<!--中间的页码,如果是当前页,添加active属性-->
{% for page in pages %}
{% if page == page_obj.number %}
<li class="active">
<a href="{% url 'blog:blog_home1' %}?page={{ page }}">{{ page }}</a>
</li>
{% else %}
<li><a href="{% url 'blog:blog_home1' %}?page={{ page }}">{{ page }}</a></li>
{% endif %}
{% endfor %}
<!--#下一页-->
{% if page_obj.has_next %}
<li>
<a href="{% url 'blog:blog_home1' %}?page={{ page_obj.next_page_number }}">下一页</a>
</li>
{% else %}
<li class="disabled"><a href="x">下一页</a></li>
{% endif %}
</ul>
<div class="sum-page">
<ul>
<li><span>共{{ page_obj.paginator.num_pages }}页</span></li>
</ul>
</div>
</div>
最后看下效果:

原文链接:http://www.itawp.com/286.html,转载请注明出处。