在具体每一篇博客中添加上一篇博客,下一篇博客将对用户更加友好。另外可以添加一个按月的分类。
添加上一篇博客,可以找到当前博客创建日期之前的所有博客,选择最后一个。添加下一篇博客,可以找到当前博客创建日期之后的所有博客,选择第一个。这个过程中需要使用filter的一些筛选条件。
大于:__gt
大于等于:__gte
小于:__lt
小于等于:__lte
包含:__contains __icontains(忽略大小写)
以xx开头:__startswith
以xx结尾:__endswith
其中之一:__in
范围:__range
- 修改
views.py
文件的blog_detail()
函数
def blog_detail(request,blog_pk):
context = {}
blog = get_object_or_404(Blog, pk=blog_pk)
context['previous_blog'] = Blog.objects.filter(created_time__gt=blog.created_time).last()
context['next_blog'] = Blog.objects.filter(created_time__lt=blog.created_time).first()
context['blog'] = blog
return render_to_response('blog/blog_detail.html', context)
- 修改
blog_detail.html
模板页面
{% extends 'base.html' %}
{% block title %}{{ blog.title }}{% endblock %}
{% block nav_blog_active %}active{% endblock %}
{% load staticfiles %}
{% block header_extends %}
<link rel="stylesheet" type="text/css" href="{% static 'blog/blog.css' %}">
{% endblock %}
{# 页面内容 #}
{% block content %}
<div class="container">
<div class="row">
<div class='col-xs-10 col-xs-offset-1'>
<h3>{{ blog.title }}</h3>
<ul class='blog_info_description'>
<li>作者:{{ blog.author }}</li>
<li>分类:<a href='{% url "blogs_with_type" blog.blog_type.pk %}'>{{ blog.blog_type }}</a></li>
<li>发表时间:{{ blog.created_time|date:"Y-m-d G:m:s" }}</li>
</ul>
<div class='blog-content'>{{ blog.content }}</div>
<div class="blog-more">
<p>上一篇:
{% if previous_blog %}
<a href="{% url 'blog_detail' previous_blog.pk %}">{{ previous_blog.title }}</a>
{% else %}
没有了
{% endif %}
</p>
<p>下一篇:
{% if next_blog %}
<a href="{% url 'blog_detail' next_blog.pk %}">{{ next_blog.title }}</a>
{% else %}
没有了
{% endif %}
</p>
</div>
</div>
</div>
</div>
{% endblock %}
通过blog.css
进行调整
....
div.blog-more {
margin-top: 1em;
}
现在详情页面显示如下:
filter
的扩展使用
进入shell
模式进行测试
(mysite_env) G:mysite_envmysite>python manage.py shell
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from blog.models import Blog
>>> Blog.objects.filter(title__contains='长文本')
<QuerySet [<Blog: <Blog: 长文本博客>>]>
>>> Blog.objects.filter(title__icontains='for 3')
<QuerySet [<Blog: <Blog: for 30>>, <Blog: <Blog: for 3>>]>
>>> Blog.objects.filter(id__in=[2,5,8])
<QuerySet [<Blog: <Blog: for 2>>, <Blog: <Blog: 长文本博客>>, <Blog: <Blog: 第二篇博客>>]>
>>> Blog.objects.filter(id__range=(5,11))
<QuerySet [<Blog: <Blog: for 5>>, <Blog: <Blog: for 4>>, <Blog: <Blog: for 3>>, <Blog: <Blog: for 2>>, <Blog: <Blog: for 1>>, <Blog: <Blog: shell模式下第一篇文章>>, <Blog: <Blog: 长文本博客>>]>
如果是想筛选出不包含目标条件的内容的话,不是使用filter
,而是使用exclude
来进行筛选。
exclude
用法与filter
一样。
添加一个按日期搜索博客的列表,是一个完全的模块,需要建立一个面板,将日期遍历出来,还需要设置路由和处理方法。
- 修改
blog urls.py
路由文件
from django.urls import path
from . import views
urlpatterns = [
path('', views.blog_list, name='blog_list'),
path('<int:blog_pk>', views.blog_detail, name='blog_detail'),
path('type/<int:blog_type_pk>', views.blogs_with_type, name='blogs_with_type'),
path('date/<int:year>/<int:month>', views.blogs_with_date, name='blogs_with_date')
]
- 修改
views.py
文件blog_list()
函数,增加一个blog_dates
context['blog_dates'] = Blog.objects.dates('created_time', 'month', order='DESC')
# 先不实现
def blogs_with_date(request, year, month):
pass
- 修改blog_list.html文件,增加日期时间的面板
.....
<div class='hidden-xs col_sm_4 col-md-3 col_lg_2'>
<div class="panel panel-default">
<div class="panel-heading">博客分类</div>
<div class="panel-body">
<ul class='blog_types'>
{% for blog_type in blog_types %}
<li><a href='{% url "blogs_with_type" blog_type.pk %}'>{{ blog_type.type_name }}</a></li>
{% empty %}
<li>暂无分类</li>
{% endfor %}
</ul>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">日期归档</div>
<div class="panel-body">
<ul>
{% for blog_date in blog_dates %}
<li>{{ blog_date|date:"Y年m月" }}</li>
{% endfor %}
</ul>
</div>
</div>
</div>
设置全局base.css
,去除列表前面的点
* {
margin: 0;
padding: 0;
}
body {
margin-top: 70px!important;
}
ul {
list-style-type: none;
}
强制刷新博客列表页
给日期面板增加超链接
blog_list.html
....
<div class="panel panel-default">
<div class="panel-heading">日期归档</div>
<div class="panel-body">
<ul>
{% for blog_date in blog_dates %}
<li>
<a href="{% url 'blogs_with_date' blog_date.year blog_date.month %}">{{ blog_date|date:"Y年m月" }}</a>
</li>
{% endfor %}
</ul>
</div>
</div>
此时点击链接会报错,因为处理方法还没有写。
- 修改
views.py
文件
def blogs_with_date(request, year, month):
context = {}
blogs_all_list = Blog.objects.filter(created_time__year=year, created_time__month=month)
paginator = Paginator(blogs_all_list, settings.EACH_PAGE_BLOGS_NUMBER)
page_num = request.GET.get('page', 1) # 获取url的页面参数(GET请求)
page_of_blogs = paginator.get_page(page_num)
current_page_num = page_of_blogs.number # 获取当前页码
# 获取当前页前后各2页
page_range = list(range(max(current_page_num - 2, 1), current_page_num)) + list(range(current_page_num, min(current_page_num + 2, paginator.num_pages) + 1))
# 加上省略号
if page_range[0] - 1 >= 2:
page_range.insert(0, '...')
if paginator.num_pages - page_range[-1] >= 2:
page_range.append('...')
# 加上首尾页码
if page_range[0] != 1:
page_range.insert(0, 1)
if page_range[-1] != paginator.num_pages:
page_range.append(paginator.num_pages)
context = {}
context['blogs_with_date'] = '%s年%s月' % (year, month)
context['blogs'] = page_of_blogs.object_list
context['page_range'] = page_range
context['page_of_blogs'] = page_of_blogs
context['blog_types'] = BlogType.objects.all()
context['blog_dates'] = Blog.objects.dates('created_time', 'month', order='DESC')
return render_to_response('blog/blogs_with_date.html', context)
- 在
blog templates blog
下面建立blogs_with_date.html
模板文件
{% extends 'blog/blog_list.html' %}
{# 页面标题 #}
{% block title %}{{ blog_type.type_name }}{% endblock %}
{% block blog_list_title %}
日期归档:{{ blogs_with_date }}
<a href='{% url "blog_list" %}'>查看全部博客</a>
{% endblock %}
此时可以从日期归档进入到相应博客列表界面。
目前views.py
文件中的代码存在大量的重复,需要进行优化。
- 修改
views.py
from django.shortcuts import render_to_response,get_object_or_404
from django.core.paginator import Paginator
from django.conf import settings
from .models import Blog, BlogType
# Create your views here.
def get_blog_list_comment_data(request, blogs_all_list):
paginator = Paginator(blogs_all_list, settings.EACH_PAGE_BLOGS_NUMBER)
page_num = request.GET.get('page', 1) # 获取url的页面参数(GET请求)
page_of_blogs = paginator.get_page(page_num)
current_page_num = page_of_blogs.number # 获取当前页码
# 获取当前页前后各2页
page_range = list(range(max(current_page_num - 2, 1), current_page_num)) + list(range(current_page_num, min(current_page_num + 2, paginator.num_pages) + 1))
# 加上省略号
if page_range[0] - 1 >= 2:
page_range.insert(0, '...')
if paginator.num_pages - page_range[-1] >= 2:
page_range.append('...')
# 加上首尾页码
if page_range[0] != 1:
page_range.insert(0, 1)
if page_range[-1] != paginator.num_pages:
page_range.append(paginator.num_pages)
context = {}
context['blogs'] = page_of_blogs.object_list
context['page_range'] = page_range
context['page_of_blogs'] = page_of_blogs
context['blog_types'] = BlogType.objects.all()
context['blog_dates'] = Blog.objects.dates('created_time', 'month', order='DESC')
return context
def blog_list(request):
blogs_all_list = Blog.objects.all()
context = get_blog_list_comment_data(request, blogs_all_list)
return render_to_response('blog/blog_list.html', context)
def blogs_with_type(request, blog_type_pk):
blog_type = get_object_or_404(BlogType, pk=blog_type_pk)
blogs_all_list = Blog.objects.filter(blog_type=blog_type)
context = get_blog_list_comment_data(request, blogs_all_list)
context['blog_type'] = blog_type
return render_to_response('blog/blogs_with_type.html', context)
def blogs_with_date(request, year, month):
blogs_all_list = Blog.objects.filter(created_time__year=year, created_time__month=month)
context = get_blog_list_comment_data(request, blogs_all_list)
context['blogs_with_date'] = '%s年%s月' % (year, month)
return render_to_response('blog/blogs_with_date.html', context)
def blog_detail(request,blog_pk):
context = {}
blog = get_object_or_404(Blog, pk=blog_pk)
context['previous_blog'] = Blog.objects.filter(created_time__gt=blog.created_time).last()
context['next_blog'] = Blog.objects.filter(created_time__lt=blog.created_time).first()
context['blog'] = blog
return render_to_response('blog/blog_detail.html', context)
刷新页面查看