Django 搭建博客项目(3)-展示首页博客列表
前两篇文章已经对项目需求和发帖功能进行了介绍以及实现,接下来本篇文章将实现对创建的发帖数据进行展示。
首先回顾下 urls.py 和 post 模块下的 urls.py 的配置情况。
urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include('post.urls')),
]
post/urls.py
urlpatterns=[
url(r'^$',views.queryAll)
]
在 post 下urls.py 请求路由回去查询所有信息,先从 queryAll 方法入手:
def queryAll(request):
# 获取所有的博客
postList = Post.objects.all().order_by('-created')
return render(request, 'index.html', {'postList': postList})
在 post/views.py 的 queryAll 方法中增加查询所有博客的方法("-created"根据创建时间排序),
同时将数据以字典方式返还给 index.html 主页中。
接下里把获取到的 postList 数据放到主页 index.html 即可。
index.html
{% block left %}
<div id="main">
{% for post in postList %}
<article class="article article-type-post">
<div class="article-meta">
<a class="article-date">
<time>{{ post.created | date:'Y-m-d H:i:s' }}</time>
</a>
<div class="article-category">
<a class="article-category-link" href="#" target="_blank">{{ post.category.cname }}</a>
</div>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="#" target="_blank">T4</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h2>{{ post.title }}</h2>
<hr>
{{ post.desc }}
<p class="article-more-link">
<a href="/post/8" target="_blank">阅读全文</a>
</p>
</div>
<footer class="article-footer">
<a data-url="存放文章的url" class="article-share-link">分享</a>
<ul class="article-tag-list">
{% for tag in post.tag.all %}
<li class="article-tag-list-item">
<a class="article-tag-list-link" href="#">{{ tag.tname}}</a>
</li>
{% endfor %}
</ul>
</footer>
</div>
</article>
{% endfor %}
<nav id="page-nav">
......
</nav>
</div>
{% endblock %}
博客主要数据在 index.html 中的 left block 模块,对应遍历了 postList 并且填充了相关数据。
运行程序,看下首页效果:
首页效果1
之前数据库中只存了两条数据,故此处只显示了两条博客数据。
完成了博客的展示,看到在博客下方还有分页功能,下面对分页功能进行完善。
首先对数据分页的逻辑进行优化处理,post/views.py 的 queryAll 方法:
def queryAll(request):
# 获取当前页面
num = request.GET.get('num',1)
num = int(num)
# 获取所有的博客
postList = Post.objects.all().order_by('-created')
# 创建分页器对象 ,每页显示一条
pageObj = Paginator(postList,1)
# 获取当前页的数据
perPageList = pageObj.page(num)
通过请求传来的页码,对数据进行分析处理获取到每页的数据。
首页效果2.png
接下来,看到在分页下方有对当前页面做上一页和下一页的判断,根据获取到的数据对 index.html 进行渲染处理。
{% block left %}
<div id="main">
{% for post in postList %}
......
{% endfor %}
<nav id="page-nav">
{% if postList.has_previous %}
<a class="extend prev" rel="next" href="/page/{{ postList.previous_page_number }}">« Prev</a>
{% endif %}
<span class="page-number current">1</span>
<a class="page-number" href="/page/2">2</a>
<a class="page-number" href="/page/3">3</a>
<a class="page-number" href="/page/4">4</a>
<a class="page-number" href="/page/5">5</a>
<a class="page-number" href="/page/6">6</a>
<a class="page-number" href="/page/7">7</a>
<a class="page-number" href="/page/8">8</a>
{% if postList.has_next %}
<a class="extend next" rel="next" href="/page/{{ postList.next_page_number }}">Next »</a>
{% endif %}
</nav>
</div>
{% endblock %}
上面针对上一页和下一页的显示进行处理,对用的点击请求需要同时在 post/url.py 中进行配置:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include('post.urls')),
]
同时需要对 post/views.py 中的分页请求逻辑继续更改优化:
def queryAll(request,num=1):
# 获取当前页面
num = int(num)
# 获取所有的博客
postList = Post.objects.all().order_by('-created')
# 创建分页器对象 ,每页显示一条
pageObj = Paginator(postList,1)
# 获取当前页的数据
perPageList = pageObj.page(num)
return render(request, 'index.html', {'postList': perPageList})
num 给默认值 num = 1,直接访问首页默认为 1 。
运行项目,查看首页展示效果:
首页效果3.png现在分页数据和上一页、下一页的后台数据逻辑已经完成,但是可以发现依然有明显问题:
1 页数显示数据问题。
2 点击页数逻辑以及高亮状态处理。
所以继续需要获取数据的页码数,继续更改 post/views.py 的数据处理逻辑:
def queryAll(request, num=1):
# 获取当前页面
num = int(num)
# 获取所有的博客
postList = Post.objects.all().order_by('-created')
# 创建分页器对象 ,每页显示一条
pageObj = Paginator(postList, 1)
# 获取当前页的数据
perPageList = pageObj.page(num)
# 生成页码数列表
# 每页开始页码
begin = (num - int(math.ceil(10.0 / 2)))
if begin < 1:
begin = 1
# 每页结束页码
end = begin + 9
if end > pageObj.num_pages:
end = pageObj.num_pages
if end <= 10:
begin = 1
else:
begin = end - 9
pageList = range(begin, end + 1)
return render(request, 'index.html', {'postList': perPageList, 'pageList': pageList})
通过 pageObj 分页器对象数据生成页码列表 pageList ,并传递到前端 index.html 页面去处理。
{% block left %}
<div id="main">
{% for post in postList %}
......
{% endfor %}
<nav id="page-nav">
{% if postList.has_previous %}
<a class="extend prev" rel="next" href="/page/{{ postList.previous_page_number }}">« Prev</a>
{% endif %}
<span class="page-number current">1</span>
{% for page in pageList %}
<a class="page-number" href="/page/{{ page }}">{{ page }}</a>
{% endfor %}
{% if postList.has_next %}
<a class="extend next" rel="next" href="/page/{{ postList.next_page_number }}">Next »</a>
{% endif %}
</nav>
</div>
{% endblock %}
nav 标签下对 pageList 的分页数数据进行了遍历的处理。
项目运行后的效果展示:
首页效果4.png两个 1 页码是因为 index.html 中多写了一个固定页面,接下来最后一步对所在页码高亮展示,同时优化 index.html 的展示效果。
post/view.py 获取当前页数据,只需要在返回中增加 currentNum 参数,而这个参数可以在请求中获取,传递给 index.html:
return render(request, 'index.html', {'postList': perPageList, 'pageList': pageList,'currentNum':num})
在 index.html 的 nav 标签模块处理 currentNum 数据:
<nav id="page-nav">
{% if postList.has_previous %}
<a class="extend prev" rel="next" href="/page/{{ postList.previous_page_number }}">« Prev</a>
{% endif %}
{% for page in pageList %}
{% if currentNum == page %}
<span class="page-number current">{{ currentNum }}</span>
{% else %}
<a class="page-number" href="/page/{{ page }}">{{ page }}</a>
{% endif %}
{% endfor %}
{% if postList.has_next %}
<a class="extend next" rel="next" href="/page/{{ postList.next_page_number }}">Next »</a>
{% endif %}
</nav>
完成上述的编写后,在后台增加多个发帖数据,运行查看效果:
首页效果5.png
欢迎关注公众号,在聊天对话框回复「博客」获取源码地址以及其他 python 相关知识。
python面面观.jpg