Django+Bootstrap+Mysql 搭建个人博客(三)
3.1.分页功能
(1)views.py
from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger def make_paginator(objects, page, num=3):
paginator = Paginator(objects, num)
try:
object_list = paginator.page(page)
except PageNotAnInteger:
object_list = paginator.page(1)
except EmptyPage:
object_list = paginator.page(paginator.num_pages)
return object_list, paginator def pagination_data(paginator, page):
"""
用于自定义展示分页页码的方法
:param paginator: Paginator类的对象
:param page: 当前请求的页码
:return: 一个包含所有页码和符号的字典
"""
if paginator.num_pages == 1:
# 如果无法分页,也就是只有1页不到的内容,则无需显示分页导航条,不用任何分页导航条的数据,因此返回一个空的字典
return {}
# 当前页左边连续的页码号,初始值为空
left = [] # 当前页右边连续的页码号,初始值为空
right = [] # 标示第 1 页页码后是否需要显示省略号
left_has_more = False # 标示最后一页页码前是否需要显示省略号
right_has_more = False # 标示是否需要显示第 1 页的页码号。
# 因为如果当前页左边的连续页码号中已经含有第 1 页的页码号,此时就无需再显示第 1 页的页码号,
# 其它情况下第一页的页码是始终需要显示的。
# 初始值为 False
first = False # 标示是否需要显示最后一页的页码号。
# 需要此指示变量的理由和上面相同。
last = False # 获得用户当前请求的页码号
try:
page_number = int(page)
except ValueError:
page_number = 1
except:
page_number = 1 # 获得分页后的总页数
total_pages = paginator.num_pages # 获得整个分页页码列表,比如分了四页,那么就是 [1, 2, 3, 4]
page_range = paginator.page_range if page_number == 1:
# 如果用户请求的是第一页的数据,那么当前页左边的不需要数据,因此 left=[](已默认为空)。
# 此时只要获取当前页右边的连续页码号,
# 比如分页页码列表是 [1, 2, 3, 4],那么获取的就是 right = [2, 3]。
# 注意这里只获取了当前页码后连续两个页码,你可以更改这个数字以获取更多页码。
right = page_range[page_number:page_number + 4] # 如果最右边的页码号比最后一页的页码号减去 1 还要小,
# 说明最右边的页码号和最后一页的页码号之间还有其它页码,因此需要显示省略号,通过 right_has_more 来指示。
if right[-1] < total_pages - 1:
right_has_more = True # 如果最右边的页码号比最后一页的页码号小,说明当前页右边的连续页码号中不包含最后一页的页码
# 所以需要显示最后一页的页码号,通过 last 来指示
if right[-1] < total_pages:
last = True elif page_number == total_pages:
# 如果用户请求的是最后一页的数据,那么当前页右边就不需要数据,因此 right=[](已默认为空),
# 此时只要获取当前页左边的连续页码号。
# 比如分页页码列表是 [1, 2, 3, 4],那么获取的就是 left = [2, 3]
# 这里只获取了当前页码后连续两个页码,你可以更改这个数字以获取更多页码。
left = page_range[(page_number - 3) if (page_number - 3) > 0 else 0:page_number - 1] # 如果最左边的页码号比第 2 页页码号还大,
# 说明最左边的页码号和第 1 页的页码号之间还有其它页码,因此需要显示省略号,通过 left_has_more 来指示。
if left[0] > 2:
left_has_more = True # 如果最左边的页码号比第 1 页的页码号大,说明当前页左边的连续页码号中不包含第一页的页码,
# 所以需要显示第一页的页码号,通过 first 来指示
if left[0] > 1:
first = True
else:
# 用户请求的既不是最后一页,也不是第 1 页,则需要获取当前页左右两边的连续页码号,
# 这里只获取了当前页码前后连续两个页码,你可以更改这个数字以获取更多页码。
left = page_range[(page_number - 3) if (page_number - 3) > 0 else 0:page_number - 1]
right = page_range[page_number:page_number + 2] # 是否需要显示最后一页和最后一页前的省略号
if right[-1] < total_pages - 1:
right_has_more = True
if right[-1] < total_pages:
last = True # 是否需要显示第 1 页和第 1 页后的省略号
if left[0] > 2:
left_has_more = True
if left[0] > 1:
first = True data = {
'left': left,
'right': right,
'left_has_more': left_has_more,
'right_has_more': right_has_more,
'first': first,
'last': last,
}
return data def index(request):
entries = models.Entry.objects.all()
page = request.GET.get('page', 1)
entry_list, paginator = make_paginator(entries, page)
page_data = pagination_data(paginator, page) return render(request, 'blog/index.html', locals())
(2)index.html
<!--/.pagination-->
<div id="paginator" class="pull-right">
<ul class="pagination">
{% if entry_list.has_previous %}
<li><a href="?page={{ entry_list.previous_page_number }}"><i
class="glyphicon glyphicon-chevron-left"></i>前一页</a></li>
{% endif %} {% if first %}
<li><a href="?page=1">1</a></li>
{% endif %} {% if left %}
{% if left_has_more %}
<span>...</span>
{% endif %} {% for i in left %}
<li><a href="?page={{ i }}">{{ i }}</a></li>
{% endfor %}
{% endif %} <li class="active"><a href="?page={{ entry_list.number }}">{{ entry_list.number }}</a></li> {% if right %}
{% for i in right %}
<li><a href="?page={{ i }}">{{ i }}</a></li>
{% endfor %} {% if right_has_more %}
<span>...</span>
{% endif %}
{% endif %} {% if last %}
<li><a href="?page={{ entry_list.num_pages }}">{{ entry_list.num_pages }}</a></li>
{% endif %} {% if entry_list.has_next %}
<li><a href="?page={{ entry_list.next_page_number }}">下一页<i
class="glyphicon glyphicon-chevron-right"></i></a></li>
{% endif %}
</ul>
</div>
</div>
3.2.分类
(1)urls.py
url(r'^category/(?P<category_id>[0-9]+)/$', views.catagory,name='blog_category'),
(2)views.py
def catagory(request,category_id):
c = models.Category.objects.get(id=category_id)
entries = models.Entry.objects.filter(category=c)
page = request.GET.get('page',1)
entry_list, paginator = make_paginator(entries, page)
page_data = pagination_data(paginator, page) return render(request, 'blog/index.html', locals())
(3)detail.html
分类:
{% for category in entry.category.all %}
<a href="{% url 'blog:blog_category' category.id %}">{{ category.name }}</a>
{% endfor %}
3.3.标签
(1)urls.py
url(r'^tag/(?P<tag_id>[0-9]+)/$', views.tag,name='blog_tag'),
(2)views.py
def tag(request,tag_id):
t = models.Tag.objects.get(id=tag_id)
if t.name == "全部":
entries = models.Entry.objects.all()
else:
entries = models.Entry.objects.filter(tags=t)
page = request.GET.get('page', 1)
entry_list, paginator = make_paginator(entries, page)
page_data = pagination_data(paginator, page)
return render(request, 'blog/index.html', locals())
(3)detail.html
标签:
{% for tag in entry.tags.all %}
<a href="{% url 'blog:blog_tag' tag.id %}">{{ tag.name }}</a>
{% endfor %}
3.4.搜索功能
(1)urls.py
url(r'^search/$', views.search,name='blog_search'),
(2)views.py
def search(request):
keyword = request.GET.get('keyword',None)
if not keyword:
error_msg = "请输入关键字"
return render(request,'blog/index.html',locals())
entries = models.Entry.objects.filter(Q(title__icontains=keyword)
| Q(body__icontains=keyword)
| Q(abstract__icontains=keyword))
page = request.GET.get('page', 1)
entry_list, paginator = make_paginator(entries, page)
page_data = pagination_data(paginator, page)
return render(request, 'blog/index.html', locals())
(3)base.html
<form class="navbar-form navbar-left" action="{% url 'blog:blog_search' %}">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search" name="keyword">
</div>
<button type="submit" class="btn btn-default">搜索</button>
</form>
3.5.博客侧边栏
(1)blog/templatetags/blog_tags.py
from django import template
from ..models import Entry,Category,Tag register = template.Library() @register.simple_tag
def get_recent_entries(num=5):
return Entry.objects.all().order_by('-created_time')[:num] @register.simple_tag
def get_popular_entries(num=5):
return Entry.objects.all().order_by('-visiting')[:num]
(2)blog/right_side_bar.html
{% load blog_tags %} <div class="row">
<div class="widget">
<h3>最新博客</h3>
{% get_recent_entries as recent_entry_list %} {% for entry in recent_entry_list %}
<div>
<a href="{{ entry.get_absolute_url }}">{{ entry.title }}</a>
<div>{{ entry.author }} 发表于:{{ entry.created_time|date:"Y年m月d日" }}</div>
</div>
{% endfor %}
</div>
</div> <div class="row">
<div class="widget">
<h3>推荐博客</h3>
{% get_popular_entries as popular_entry_list %} {% for entry in popular_entry_list %}
<div>
<a href="{{ entry.get_absolute_url }}">{{ entry.title }}</a>
<span class="badge" style="color: white;background-color: darkgreen">{{ entry.visiting }}</span>
</div>
{% endfor %}
</div>
</div>
(3)index.html
添加进去
<div class="col-md-3">
{% include 'blog/right_site_bar.html' %}
</div>
(4)detail.html一样添加
Django+Bootstrap+Mysql 搭建个人博客(三)的更多相关文章
- Django+Bootstrap+Mysql 搭建个人博客(一)
1.1.环境搭建 (1)虚拟环境 mkvirtualenv website pip install django==1.11.7 (2)创建项目和app:website和blog (3)设置中文set ...
- Django+Bootstrap+Mysql 搭建个人博客(五)
5.1.自定义403,404和500页面 (1)website/urls.py from blog import views as blog_views handler403 = blog_views ...
- Django+Bootstrap+Mysql 搭建个人博客(四)
4.1.博客分类 (1)blog_tags.py @register.simple_tag def get_categories(): return Category.objects.all() @r ...
- Django+Bootstrap+Mysql 搭建个人博客(二)
2.1.博客首页设计 (1)settings.py MEDIA_ROOT = os.path.join(BASE_DIR,'media').replace("//","/ ...
- Django+Bootstrap+Mysql 搭建个人博客(六)
6.1.comments插件 (1)安装 pip install django-contrib-comments (02)settings INSTALLED_APPS = [ 'django.con ...
- Django+Bootstrap+Mysql 搭建个人博客 (六)
6.1.comments插件 (1)安装 pip install django-contrib-comments (02)settings INSTALLED_APPS = [ 'django.con ...
- Python Web开发:Django+BootStrap实现简单的博客项目
创建blog的项目结构 关于如何创建一个Django项目,请查看[Python Web开发:使用Django框架创建HolleWorld项目] 创建blog的数据模型 创建一个文章类 所有开发都是数据 ...
- django入门--django-blog-zinnia搭建个人博客
1.安装python 选择合适python2.7及以上版本安装https://www.python.org/downloads/ 2.建立虚拟环境 这不是必须的,但是建议使用,为每个项目单独引入依赖, ...
- Django两天搭建个人博客
传送门:https://github.com/1417766861/django-blog(可直接运行,上面有步骤) 效果: 首页: 侧栏: 详情页面: 修改头像,资料,文章发布: 支持添加标签拖拽 ...
随机推荐
- Windows phone 8.1之数据绑定(Data Binding)
学习Winphone8.1的时候经常需要对Slider进行数据绑定后使之视觉化,方便调节Slider的值. 数据绑定分为源(Source)和目标(Target),Source一般分为两种,其他控件的数 ...
- Tomcat映射路径
打开tomcat安装包,在config目录下修改server.xml文件: 在<Host>标签中添加: <Context path="" docBase=&quo ...
- xxl-job调度中心配置以及常见错误
项目结构图 启动步骤: 1.检查 /xxl-job/xxl-job-admin/src/main/resources/xxl-job-admin.properties 下的JDBC链接.登录账号. 2 ...
- 利用kibana插件对Elasticsearch进行bool查询
#bool查询#老版本的filtered查询已经被bool代替#用 bool包括 must should must_not filter来完成 ,格式如下:#bool:{# "filter ...
- 展开被 SpringBoot 玩的日子 《 四 》 Session 会话共享
共享Session-spring-session-data-redis 分布式系统中,sessiong共享有很多的解决方案,其中托管到缓存中应该是最常用的方案之一. Spring Session官方说 ...
- BZOJ.4160.[NEERC2009]Exclusive Access 2(状压DP Dilworth定理)
BZOJ DAG中,根据\(Dilworth\)定理,有 \(最长反链=最小链覆盖\),也有 \(最长链=最小反链划分数-1\)(这个是指最短的最长链?并不是很确定=-=),即把所有点划分成最少的集合 ...
- cgi、fast-cgi、php-pfm关系
CGI是一种规定了服务器和处理进程的数据传输格式的协议 如:nginx 和 php处理进程之间的数据传输是使用cgi格式来相互传输数据 CGI 是 接到请求,fork一条进程来处理,处理完后就退出. ...
- RSP小组——团队冲刺博客三
RSP小组--团队冲刺博客三 冲刺日期:2018年12月12日 各成员今日(12.12)完成的任务 马瑞蕃页面布局 李闻洲音乐代码的实现 赵乾宸,找bug,处理bug,使游戏滑动,消除实现 蒋子行会议 ...
- 三色GDOI
前面说点什么.. 翻了翻别人的游记.. 发现自己从来没写过gdoi的游记.. 那就.. 一起写完它吧.. GDOI2015 肇庆 没啥印象,只有复联2的首映.. 那时候真的是什么都不懂.. 就是外出打 ...
- It is difficult to the point of impossiblity for sb to image a time when ...
对sb而言很难想象一段..的时光.