视频链接:15.上下篇博客和按月分类
filter筛选条件
filter()返回QuerySet。
- 等于:直接筛选
- 大于:__gt
- 大于等于:__gte
- 小于:__it
- 小于等于:__ite
- 包含:__contains
- 包含(忽略大小写):__icontains (SQLite不支持对大小写的区分)
- 开头是:__startswith
- 结尾是:__endswith
- 其中之一:__in
- 范围:__range
添加“上一篇”和“下一篇”,修改blog/view.py:
...
def blog_detail(request, blog_pk):
blog = get_object_or_404(Blog, pk=blog_pk)
context = {}
context['blog'] = blog
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()
return render_to_response('blog/blog_detail.html', context)
...
last()获取查询到的最后一条;first()获取查询到的第一条。
修改blog/templates/blog/blog_detail.html:
...
{% 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 H:n: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/static/blog/blog.css:
...
div.blog-more {
margin-top: 1em;
}
exclude排除条件
用法和filter()一样,也返回QuerySet。比如取pk不等于3的:
Blog.objects.exclude(pk=3)
条件中的双下划线
- 字段查询类型:例如filter()不能直接用”>=”之类的运算符,需要某种东西代替,比如“__gt=”表示大于。
- 外键拓展:例如,blog/views.py中的blogs_with_type()可改为:
...
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__id=blog_type_pk)
...
-
日期拓展;例如,查询创建年份为2017年的博文: -
Blog.objects.filter(created_time__year=2017)
- 支持链式查询
-
按月分类
修改blog/views.py:
... def blogs_with_date(request, year, month): blogs_all_list = Blog.objects.filter(created_time__year=year, created_time__month=month) # 获取年月符合要求的博文 paginator = Paginator(blogs_all_list, settings.BLOGS_NUM_PER_PAGE) page_num = request.GET.get('page', 1) # 获取url的页码参数。GET返回字典,page_num默认为1 page_of_blogs = paginator.get_page(page_num) current_page_num = page_of_blogs.number # 获取当前页码 # 获取前后各页 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['page_of_blogs'] = page_of_blogs context['blog_types'] = BlogType.objects.all() context['page_range'] = page_range context['blog_dates'] = Blog.objects.dates('created_time', 'month', order='DESC') # created_time按月降序 context['blogs_with_date'] = "%s年%s月" % (year, month) return render_to_response('blog/blogs_with_date.html', context) ...
新建blog/templates/blogs_with_date.html:
{% extends 'blog/blog_list.html'%} {% block title %} {{ blog_type.type_name }} {% endblock%} {% block nav_blog_active %} active {% endblock %} {% block blog_list_title %} 日期归档:{{ blogs_with_date }} <a href="{% url 'blog_list' %}">查看全部博文</a> {% endblock %}
修改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'), ]
修改blog/templates/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 class="blog-types"> {% 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> </div> ...
整理代码,减少重复
修改blog/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 def get_blog_list_common_data(request, blogs_all_list): paginator = Paginator(blogs_all_list, settings.BLOGS_NUM_PER_PAGE) page_num = request.GET.get('page', 1) # 获取url的页码参数。GET返回字典,page_num默认为1 page_of_blogs = paginator.get_page(page_num) current_page_num = page_of_blogs.number # 获取当前页码 # 获取前后各页 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['page_of_blogs'] = page_of_blogs # context['blogs_count'] = Blog.objects.all().count() context['blog_types'] = BlogType.objects.all() context['page_range'] = page_range context['blog_dates'] = Blog.objects.dates('created_time', 'month', order='DESC') # created_time按月降序 return context 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 blog_detail(request, blog_pk): blog = get_object_or_404(Blog, pk=blog_pk) context = {} context['blog'] = blog 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() return render_to_response('blog/blog_detail.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)