1. 前后博文
1.1 filter筛选条件
·Articles.objects.filter(article_type?)
等于:直接筛选 大于:gt (greather than) 大于等于:gte 小于:lt (less than) 小于等于:lte 包含:(加i忽略大小写)contains 开头是:startswith 结尾是:endswith 其中之一:in 范围:range 日期:year __month
>>> from s2aclab.models import Articles>>> Articles.objects.filter(title__contains='django')<QuerySet []>>>> Articles.objects.filter(title__contains='code')<QuerySet [<Articles: <Article:第一篇code>>]>>>> Articles.objects.filter(title__icontains='cOde')<QuerySet [<Articles: <Article:第一篇code>>]>>>> Articles.objects.filter(id__in=[1,3,4,6])<QuerySet [<Articles: <Article:for 3>>, <Articles: <Article:for 1>>, <Articles: <Article:for 2>>, <Articles: <Article:第一篇research>>]>>>>
修改article_details.html 和views中的类
def article_details(request, art_pk):
context = {}
article = get_object_or_404(Articles, pk=art_pk)
context['article'] = article
context['next_article'] = Articles.objects.filter(created_time__gt=article.created_time).last() # .last()表示取最后一条
context['previous_article'] = Articles.objects.filter(
created_time__lt=article.created_time).first() # .first()表示取第一条
return render(request, 'article_details.html', context)
<!-- 前后翻页 -->
<nav aria-label="...">
<ul class="pager">
{%if previous_article %}
<li class="previous"><a href="{% url 'article_details' previous_article.pk %}"><span
aria-hidden="true">←</span>Previous</a></li>
{% else %}
{% endif %}
{% if next_article %}
<li class="next"><a href="{% url 'article_details' next_article.pk %}">Next <span
aria-hidden="true">→</span></a></li>
{% else %}
{% endif %}
</ul>
</nav>
2 博文分类
2.1 条件中的双下划线
字段查询类型 外键扩展(以博客分类为例) 日期拓展(以月份分类为例) 支持链式查询:可以一直链接下去
>>> Articles.objects.filter(created_time__month=5)
<QuerySet [<Articles: <Article:第一篇code>>, <Articles: <Article:第一篇research>>]>
dates()¶
dates(field,kind,order =’ASC’)¶
返回一个QuerySet,其结果是一个datetime.date 对象列表,该对象列表表示的内容中特定种类的所有可用日期QuerySet。
field应该是DateField您的模型的名称。 kind应该是"year","month"或"day"。datetime.date结果列表中的每个 对象都将“截断”到给定 type。
"year"返回该字段的所有不同年份值的列表。"month"返回该字段的所有不同年份/月份值的列表。"day"返回该字段的所有不同年/月/日值的列表。
order(默认为'ASC')应为'ASC'或 'DESC'。这指定了如何订购结果。
例子:
>>> Entry.objects.dates('pub_date', 'year')
[datetime.date(2005, 1, 1)]
>>> Entry.objects.dates('pub_date', 'month')
[datetime.date(2005, 2, 1), datetime.date(2005, 3, 1)]
>>> Entry.objects.dates('pub_date', 'day')
[datetime.date(2005, 2, 20), datetime.date(2005, 3, 20)]
>>> Entry.objects.dates('pub_date', 'day', order='DESC')
[datetime.date(2005, 3, 20), datetime.date(2005, 2, 20)]
>>> Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day')
[datetime.date(2005, 3, 20)]
在views.py中的articles_list()中添加
context['article_dates'] = Articles.objects.dates('created_time','month',order='DESC')
articles_list.html中添加日期分类框
<!-- date categories -->
<div class="panel panel-default">
<div class="panel-heading">Date Categories</div>
<div class="panel-body">
<ul class="article_date">
{% for article_date in article_dates %}
<li>
<a href="{% url 'article_with_date' article_date.year article_date.month %}">
{{ article_date| date:"Y-m" }}
</a>
</li>
{% empty %}
<li></li>
{% endfor %}
</ul>
</div>
</div>
<!-- END date categories -->
新建artilce_with_date.html
<!-- coding=utf8 -->
{% extends 'articles_list.html' %}
<!--title -->
{% load static%}
{% block title %}
{{article_type.type_name}}
{% endblock %}
{% block article_list_title %}
{{ article_with_date }} | {{ page_of_articles.paginator.count }} Blogs <a href="{% url 'articles_list' %}"></a>
{% endblock %}
新建article_with_date()
def article_with_date(request, year, month):
articles_all_list = Articles.objects.filter(created_time__year=year, created_time__month=month)
context = get_all_common_data(request,articles_all_list)
context['article_with_date'] = '%s-%s'%(year,month)
return render(request, 'article_with_date.html', context)
将articles_list() article_with_type() 以及 article_with_date()中公共的数据部分取出新建get_all_common_data()函数,简化代码
def get_all_common_data(request,articles_all_list):
paginator = Paginator(
articles_all_list, settings.ARTICLE_NUMBER_EACH_PAGE) # 4篇一页
# 获取页码参数(GET请求) .GET 字典 使用get方法判断是否有page值,没有返回1
page_num = request.GET.get("page", 1)
# 输入许可字符范围外的字符会返回1
page_of_articles = paginator.get_page(page_num)
# 获取当前页
current_page = page_of_articles.number
# 页码显示范围
page_range = [i for i in range(
current_page-2, current_page+3) if 0 < i <= paginator.num_pages]
# 第一页
if page_range[0] >= 2:
page_range.insert(0, 1) # 第一位插入1页码
if page_range[1] != 2:
page_range.insert(1, '...') # 加上...
# 最后一页
if page_range[-1] <= paginator.num_pages - 1:
if page_range[-1] != paginator.num_pages - 1:
page_range.append('...') # 加上...
page_range.append(paginator.num_pages)
context = {}
# context['articles'] = page_of_articles.object_list # 前端页面
context['page_of_articles'] = page_of_articles # 当前页码
context['article_types'] = ArticleType.objects.all()
context['article_dates'] = Articles.objects.dates('created_time', 'month', order='DESC')
context['page_range'] = page_range
return context
2.2 博文分类统计
获取对应分类的博文数量 python 直接查询
新建get_categories_count()
类对象article_type(ArticleType)添加属性.article_count
新建字典article_dates_dict = dict()
# 获取对应的分类与博文数
def get_all_common_data(request,articles_all_list):
...
context['article_types'] = ArticleType.objects.annotate(article_count=Count('art_art')) # 所有分类
context['article_dates'] = get_categories_count() # 日期分类与数量
def get_categories_count():
'''
# 获取对应分类的博文数量 简单粗暴方法 占服务器
article_types = ArticleType.objects.all()
artcile_types_list = []
for article_type in article_types:
# 类对象`article_type(ArticleType)`添加属性`.article_count`
article_type.article_count = Articles.objects.filter(
article_type=article_type).count()
artcile_types_list.append(article_type)
# 获取对应分类的博文数量 annotate
# ArticleType.objects.annotate(article_count=Count('art_art')) # 返回sql语句
'''
# 获取对应日期的博文数量
article_dates = Articles.objects.dates('created_time', 'month', order = 'DESC')
article_dates_dict = dict()
for date in article_dates:
article_dates_dict[date] = Articles.objects.filter(created_time__year=date.year,
created_time__month=date.month).count()
return article_dates_dict
articles_list.html
<ul class="article_type">
{% for type in article_types %}
<li>
<a href="{% url 'article_with_type' type.pk %}">
{{ type.type_name }} ({{type.article_count}})
</a>
</li>
{% empty %}
<li></li>
{% endfor %}
</ul>
<ul class="article_date">
{% for article_date,article_count in article_dates.items %}
<li>
<a href="{% url 'article_with_date' article_date.year article_date.month %}">
{{ article_date| date:"Y-m" }} ({{article_count}})
</a>
</li>
{% empty %}
<li></li>
{% endfor %}
</ul>

annotate注释——拓展查询字段
views.py get_all_common_data()
# 返回sql语句
context['article_types'] = ArticleType.objects.annotate(article_count=Count('art_art')) # 所有分类
需要在models.py中修改
class Articles(models.Model):
article_type = models.ForeignKey(ArticleType,on_delete=models.DO_NOTHING,related_name='art_art')
