Django个人博客开发(八)前端动态页面开发
发布时间:2018-04-14 12:04:01分类:编程开发阅读:1259
概述
本节继续在视图文件blog/views.py中添加视图函数,以完成前端各页面的动态数据渲染。在应用URL文件blog/urls.py中添加相应的路由,然后完善各前端页面和模块的链接。
前端动态页面开发思路图
1、视图函数,文件blog/views.py
1.1添加文章详情页视图
为了让文章详情请求能清晰知道文章标题,而不仅仅是个id数字,因此使用“article-detail/2/DjangoGe-Ren-Bo-Ke-Kai-Fa/”的URL形式,参数包含文章id和文章slug。
from django.shortcuts import render,get_object_or_404
from django.conf import settings
from django.db.models import Q # filter(~Q(name=''))过滤表示不等于
from .models import Category, Tag, Article, Comment, Links
# 文章详情页视图
def article_detail(request, id, slug):
# 返回匹配id和slug的文章对象,否则的404错误
article = get_object_or_404(Article, id=id, slug=slug)
return render(request, 'blog/article.html', locals())
1.2添加文章列表页视图
文章列表有两种情况,一种为指定文章类目下的文章列表,另一种为指定标签下的文章列表。当列表数据过多,就需要对列表数据进行分页浏览,因此需要给文章列表使用分页。
from django.shortcuts import render, get_object_or_404
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.conf import settings
from django.db.models import Q # filter(~Q(name=''))过滤表示不等于
from .models import Category, Tag, Article, Comment, Links
# 文章列表页视图
def article_list(request, category_id=None, tag_id=None, page=1):
# 从配置文件中获取每页显示文章数
per_page = settings.PER_PAGE
# 根据url中匹配的值,判断是文章类目列表还是标签文章列表
if category_id:
category = get_object_or_404(Category, id=category_id)
articles_list = Article.objects.filter(category_id=category_id)
else:
tag = get_object_or_404(Tag, id=tag_id)
articles_list = tag.article.all()
# 实例化分页对象
paginator = Paginator(articles_list, per_page)
try:
current_page = paginator.page(page)
except PageNotAnInteger:
current_page = paginator.page(1)
except EmptyPage:
current_page = paginator.page(paginator.num_pages)
# 当前页(某一页/第一页/最后一页)的所有文章记录对象
articles = current_page.object_list
return render(request, 'blog/articlelist.html', locals())
2、 请求路由,文件blog/urls.py
2.1添加文章详情页路由
from django.conf.urls import url
from django.views.generic import TemplateView # 通用视图,可直接将静态映射为视图函数
from . import views
urlpatterns = [
url(r'^$', views.index, name='home'),
url(r'^article-detail/(?P<id>\d+)/(?P<slug>[-\w]+)/$', views.article_detail, name='article_detail'), # 将正则匹配的id和slug传递给视图函数
]
由于文章详情页请求使用“article-detail/2/DjangoGe-Ren-Bo-Ke-Kai-Fa/”的URL形式,而id和slug都是针对当前文章实例,因此可以在文章数据模型类中定义一个get_absolute_url()方法,返回当前文章的请求URL,从而在需要文章请求URL的位置,直接调用该文章的get_absolute_url()方法。
在blog/models.py文件Article数据模型类中添加get_absolute_url()方法
from django.shortcuts import reverse
# 文章表数据模型
class Article(models.Model):
……部分省略……
# 获取文章详情链接URL
def get_absolute_url(self):
return reverse('blog:article_detail', args=[self.id, self.slug]) # reverse()函数通过url别名返回对应的url路径
2.2添加文章列表页路由
文章列表页分为分类文章列表和标签文章列表两类,以url路径中含有/tag/的为标签文章列表。而每类文章列表页路由分为两种情况,一种为不通过分页链接进入列表页,没有page参数;另一种是通过分页链接切换列表页,则包含page参数。
urlpatterns = [
url(r'^article-list/(?P<category_id>\d+)/$', views.article_list, name='article_list'), # 通过导航进入的列表没有page参数,则使用视图函数的默认值page=1
url(r'^article-list/(?P<category_id>\d+)/(?P<page>\d)/$', views.article_list, name='article_list'),
url(r'^article-list/(tag)/(?P<tag_id>\d+)/$', views.article_list, name='article_list'), # 通过标签链接进入的列表没有page参数,则使用视图函数默认值page=1,注意标签页列表路径含有/tag/
url(r'^article-list/(tag)/(?P<tag_id>\d+)/(?P<page>\d)/$', views.article_list, name='article_list'),
]
3、前端模板
3.1文章详情页模板,文件blog/article.html
{% extends "blog/baseblock/subbase.html" %}
{% load staticfiles %}
{% block title %}{{ article.title }}{% endblock %}
{% block content_box %}
<div class="f_box">
<p class="a_title">{{ article.title }}</p>
<p class="p_title"></p>
<p class="box_p"><span>发布时间:{{ article.publish | date:'Y-m-d H:m:s' }}</span><span>分类:{{ article.category.name }}</span><span>阅读:9999</span></p>
<!-- 可用于内容模板 -->
</div>
<ul class="about_content">
{{ article.content | safe }}
</ul>
<!-- <div class="nextinfos">
<p>上一篇:<a href="/">区中医医院开展志愿服务活动</a></p>
<p>下一篇:<a href="/">广安区批准“单独两孩”500例</a></p>
</div>-->
<!-- 可用于内容模板 -->
<!-- container代码 结束 -->
{% endblock %}
3.2文章列表页模板,文件blog/articlelist.html
{% extends "blog/baseblock/subbase.html" %}
{% load staticfiles %}
{% block title %}
{% if tag %}
【{{ tag.name }}】文章列表
{% else %}
【{{ category.name }}】文章列表
{% endif %}
{% endblock %}
{% block content_box %}
<div class="bloglist f_l">
{% include "blog/baseblock/list.html" %}
<div class="blank"></div>
{# 文章列表分为文章类目文章列表和文章标签文章列表,因此针对这两种情况判断指定不同的分页 #}
{% if tag %}
<div class="pagelist">
页次:{{ current_page.number }}/{{ current_page.paginator.num_pages }}
每页:{{ per_page }} 总数:{{ current_page.paginator.count }} <a href="{% url 'blog:article_list' 'tag' tag.id 1 %}">首页</a>
{% if current_page.has_previous %}
<a href="{% url 'blog:article_list' 'tag' tag.id current_page.previous_page_number %}">上一页</a>
{% endif %}
{% if current_page.has_next %}
<a href="{% url 'blog:article_list' 'tag' tag.id current_page.next_page_number %}">下一页</a>
{% endif %}
<a href="{% url 'blog:article_list' 'tag' tag.id current_page.paginator.num_pages %}">尾页</a>
</div>
{% else %}
<div class="pagelist">
页次:{{ current_page.number }}/{{ current_page.paginator.num_pages }}
每页:{{ per_page }} 总数:{{ current_page.paginator.count }} <a href="{% url 'blog:article_list' category.id 1 %}">首页</a>
{% if current_page.has_previous %}
<a href="{% url 'blog:article_list' category.id current_page.previous_page_number %}">上一页</a>
{% endif %}
{% if current_page.has_next %}
<a href="{% url 'blog:article_list' category.id current_page.next_page_number %}">下一页</a>
{% endif %}
<a href="{% url 'blog:article_list' category.id current_page.paginator.num_pages %}">尾页</a>
</div>
{% endif %}
</div>
<div class="r_box f_r">
{% include "blog/baseblock/photorecommend.html" %}
{% include "blog/baseblock/hitsort.html" %}
{% include "blog/baseblock/tags.html" %}
{% include "blog/baseblock/links.html" %}
{# <div class="ad"> <img src="{% static 'blog/images/03.jpg' %}"> </div>#}
</div>
{% endblock %}
4、完善各模块及之间链接
4.1 页头,文件blog/baseblock/header.html
{% for nav_jszt in nav_jszt_category %}
<li><a href="{% url 'blog:article_list' nav_jszt.id %}">{{ nav_jszt.name }}</a></li>
{% endfor %}
{% for nav_shsb in nav_shsb_category %}
<li><a href="{% url 'blog:article_list' nav_shsb.id %}">{{ nav_shsb.name }}</a></li>
{% endfor %}
4.2 阅读排行,文件blog/baseblock/hitsort.html
{% for article in hits_articles %}
<li><a href="{{ article.get_absolute_url }}" target="_blank" title="【{{ article.category.name }}】{{ article.title }}">{{ article.title }}</a></li>
{% endfor %}
4.3 图文推荐,文件blog/baseblock/photorecommend.html
{% for article in recommend_articles %}
<li><a href="{{ article.get_absolute_url }}" title="{{ article.title }}"><img src="{{ article.picture.url }}"><b>{{ article.title | truncatechars:18 }}</b></a>
<p><span class="tulanmu"><a href="#">{{ article.category.name }}</a></span><span class="tutime">{{ article.publish | date:'Y-m-d' }}</span></p>
</li>
{% endfor %}
4.4 标签云,文件blog/baseblock/tags.html
{% for tag in tags %}
<li><a href="{% url 'blog:article_list' 'tag' tag.id %}">{{ tag.name }}({{ tag.article_count }})</a></li>
{% endfor %}
4.5 文章列表,文件blog/baseblock/list.html
{% for article in articles %}
<h3><a href="{{ article.get_absolute_url }}">【{{ article.category.name }}】{{ article.title }}</a></h3>
<figure><img src="{% if article.picture %}{{ article.picture.url }}{% else %}{% static 'blog/images/img_2.jpg' %}{% endif %}" alt="【{{ article.category.name }}】{{ article.title }}"></figure>
<ul>
<p>{{ article.abstract }}</p>
<a title="【{{ article.category.name }}】{{ article.title }}" href="{{ article.get_absolute_url }}" class="readmore">阅读全文>></a>
</ul>
<p class="dateview"><span>{{ article.publish | date:'Y-m-d' }}</span><span>阅读:9999次</span><span>分类:[<a href="{% url 'blog:article_list' article.category.id %}">{{ article.category.name }}</a>]</span></p>
{% empty %}
<p>还没有发布文章</p>
{% endfor %}
4.6 子基础模板,文件blog/baseblock/subbase.html
{% if tag %}
<h2 class="nh1"><span>您现在的位置是:<a href="/">网站首页</a>>><a href="{% url 'blog:article_list' 'tag' tag.id %}">【{{ tag.name }}】</a></span><b>【{{ tag.name }}】</b></h2>
{% elif category %}
<h2 class="nh1"><span>您现在的位置是:<a href="/">网站首页</a>>><a href="{% url 'blog:article_list' category.id %}">{{ category.name }}</a></span><b>{{ category.name }}</b></h2>
{% else %}
<h2 class="nh1"><span>您现在的位置是:<a href="/">网站首页</a>>><a href="{% url 'blog:article_list' article.category_id %}">{{ article.category.name }}</a></span><b>{{ article.category.name }}</b></h2>
{% endif %}
代码查看:https://github.com/xdao07/xdsite/tree/v0.0.5
代码下载:git clone --branch v0.0.5 https://github.com/xdao07/xdsite.git