【Django2.0学习笔记】15.上下篇博客和按月分类

15、上下篇博客和按月分类

我们打开一篇博文之后,如果我们想要看上一篇下一篇,有一个直接的链接可以点击,就会方便很多,那么自然而然就会产生这样的需求:有上一篇下一篇的按钮

1、上一篇和下一篇博客

  • 对比当前博客,得到上一篇或下一篇
    在这里插入图片描述

比如:
在这里插入图片描述
假如我们打开的是 id=3 的博客,它的上一篇就是 id=4 的博客,下一篇就是id=2的博客。既然我们是按照创建时间倒序排序的,那么能不能按照创建时间来进行。这里我们就可以用filter,通过某些条件进行查询,得到 QuerySet,比如想找到上一篇博客,即日期比2018年1月27号大的所有博客,然后取查询结果里的最后一条;想找到下一篇博客,即日期比2018年1月27号小的所有博客,然后取查询结果里的第一条。

2、filter筛选条件

  • 等于:直接筛选
  • 其他常用查找类型:
    • 大于:__gt(greater than)
    • 大于等于:__gte
    • 小于:__lt(less than)
    • 小于等于:__lte
    • 包含:__contains(加 i 忽略大小写)
    • 开头是:__startswith
    • 结尾是:__endswith
    • 其中之一:__in
    • 范围:__range
      在这里插入图片描述

修改views.py如下:
在这里插入图片描述

blog = get_object_or_404(Blog, pk=blog_pk)
context['previous_blog'] = Blog.objects.filter(created_time__gt=blog.created_time).last() # 找到比当前博客创建日期大的所有博客集合,last()取最后一条
context['next_blog'] = Blog.objects.filter(created_time__lt=blog.created_time).first() # 找到比当前博客创建日期小的所有博客集合,first()取第一条
context['blog'] = blog

修改blog_detail.html如下:
在这里插入图片描述

<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>

修改blog.css如下:
在这里插入图片描述

演示其他filter筛选条件:
在这里插入图片描述

3、exclude 排除条件

  • 用法和filter一样,都是得到查询(QuerySet)
  • 相当于filter条件取反
  • filter等于=>不等于
    在这里插入图片描述
    在这里插入图片描述

4、条件中的双下划线

  • 字段查询类型
  • 外键拓展(以博客分类为例)
  • 日期拓展(以月份分类为例)
  • 支持链式查询:可以一直链接下去
    在这里插入图片描述

在这里插入图片描述

除了按照博客类型分类,我们还能不能按照发表日期(年份月份)来进行分类呢?
修改blog\urls.py如下:
在这里插入图片描述
修改blog_list.html如下:
在这里插入图片描述
修改blog/views.py如下:
在这里插入图片描述
其中context['blog_dates'] = Blog.objects.dates('created_time', 'month', order='DESC'),可以参考django官方文档在这里插入图片描述
修改全局变量mysite\static\base.css如下:
在这里插入图片描述

继续完善blog/views.py中的blogs_with_date方法 如下:
在这里插入图片描述

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)	# 获取页码参数(GET请求)
	page_of_blogs = paginator.get_page(page_num)	# 这里get_page方法,如果获取到的是其他字符而不是整数数字,会自动转化为1,使得它是处于有效的范围内
	current_page_num = page_of_blogs.number # 获取当前页码
	# 获取当前页码前后各2页的页码范围
	page_range = list(range(max(current_page_num-2, 1), min(current_page_num+3, 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_of_blogs'] = page_of_blogs	# 返回具体的博客给前端模板页面
	context['page_range'] = page_range
	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)

创建blogs_with_date.html(类似于blogs_with_type.html)
在这里插入图片描述

<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\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中各个方法的代码,可以看到有很多重复的代码,我们进行完善一下,将各个方法的公共部分代码放到一个新建的方法中,然后其他方法调用这个公共方法即可:
在这里插入图片描述
在这里插入图片描述

# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\blog\views.py
from django.shortcuts import render_to_response, get_object_or_404 # render_to_response:用模板页面输出响应内容
from django.core.paginator import Paginator
from django.conf import settings
from .models import Blog, BlogType # 引入BlogType这个模型

def get_blog_list_common_data(request, blogs_all_list):
	paginator = Paginator(blogs_all_list, settings.EACH_PAGE_BLOGS_NUMBER)	# 每多少篇博客作为一页
	page_num = request.GET.get('page', 1)	# 获取页码参数(GET请求)。# 看有没有‘page’这个属性,如果没有,则默认给1
	page_of_blogs = paginator.get_page(page_num)	# 这里get_page方法,如果获取到的是其他字符而不是整数数字,会自动转化为1,使得它是处于有效的范围内
	current_page_num = page_of_blogs.number # 获取当前页码
	# 获取当前页码前后各2页的页码范围
	page_range = list(range(max(current_page_num-2, 1), min(current_page_num+3, 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_of_blogs'] = page_of_blogs	# 修改。返回具体的博客给前端模板页面
	context['page_range'] = page_range
	context['blog_types'] = BlogType.objects.all()
	context['blog_dates'] = Blog.objects.dates('created_time', 'month', order='DESC') 
	return context

# 需要两个处理方法:1.访问博客列表;2.显示具体的blog页面
def blog_list(request):
	blogs_all_list = Blog.objects.all()	# 获取所有博客
	context = get_blog_list_common_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_common_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_common_data(request, blogs_all_list)
	context['blogs_with_date'] = '%s年%s月' % (year, month)
	return render_to_response("blog/blogs_with_date.html", context)

# 具体的blog页面需要传一个参数进来,这个参数就是主键id(主键pk)
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() # 找到比当前博客创建日期大的所有博客集合,last()取最后一条
	context['next_blog'] = Blog.objects.filter(created_time__lt=blog.created_time).first() # 找到比当前博客创建日期小的所有博客集合,first()取第一条
	context['blog'] = blog
	return render_to_response('blog/blog_detail.html', context)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值