一.日期歸檔查詢(知識點--我的站點頁面的日期查詢)css
1 date_formathtml
======================date,time,datetime===============mysql
create table t_mul_new (d date,t time,dt datetime);sql
insert into t_mul values(now(),now(),now());數據庫
insert * from t_mul;django
mysql > select * from t_mul;bootstrap
mysql> use test2 Database changed mysql> mysql> create table t_mul_new(d date, t time, dt datetime); Query OK, 0 rows affected (2.11 sec) mysql> insert into t_mul_new values(now(), now(), now()); Query OK, 1 row affected, 1 warning (0.49 sec) mysql> select * from t_mul_new; +------------+----------+---------------------+ | d | t | dt | +------------+----------+---------------------+ | 2018-08-02 | 22:59:15 | 2018-08-02 22:59:15 | +------------+----------+---------------------+ 1 row in set (0.00 sec) mysql> select dt from t_mul_new; +---------------------+ | dt | +---------------------+ | 2018-08-02 22:59:15 | +---------------------+ 1 row in set (0.00 sec) mysql> select date_format(dt, "%Y-%m") from t_mul_new; +--------------------------+ | date_format(dt, "%Y-%m") | +--------------------------+ | 2018-08 | +--------------------------+ 1 row in set (0.05 sec) mysql> select date_format(dt, "%Y-%m-%d") from t_mul_new; +-----------------------------+ | date_format(dt, "%Y-%m-%d") | +-----------------------------+ | 2018-08-02 | +-----------------------------+ 1 row in set (0.00 sec) mysql> select date_format(dt, "%Y/%m/%d") from t_mul_new; +-----------------------------+ | date_format(dt, "%Y/%m/%d") | +-----------------------------+ | 2018/08/02 | +-----------------------------+ 1 row in set (0.00 sec) mysql>
2.extra函數
extra(select=None, where=None, params=None,
tables=None, order_by=None, select_params=None)
有些狀況下,Django的查詢語法難以簡單的表達複雜的 WHERE 子句,對於這種狀況, Django 提供了 extra() QuerySet修改機制 — 它能在 QuerySet生成的SQL從句中注入新子句佈局
extra能夠指定一個或多個 參數,例如 select, where or tables. 這些參數都不是必須的,可是你至少要使用一個!要注意這些額外的方式對不一樣的數據庫引擎可能存在移植性問題.(由於你在顯式的書寫SQL語句),除非萬不得已,儘可能避免這樣作url
The select 參數可讓你在 SELECT 從句中添加其餘字段信息,它應該是一個字典,存放着屬性名到 SQL 從句的映射。
queryResult=models.Article
.objects.extra(select={'is_recent': "create_time > '2017-09-05'"})
結果集中每一個 Entry 對象都有一個額外的屬性is_recent, 它是一個布爾值,表示 Article對象的create_time 是否晚於2017-09-05.
練習:
# in sqlite: article_obj=models.Article.objects
.filter(nid=1)
.extra(select={"standard_time":"strftime('%%Y-%%m-%%d',create_time)"})
.values("standard_time","nid","title") print(article_obj) # <QuerySet [{'title': 'MongoDb 入門教程', 'standard_time': '2017-09-03', 'nid': 1}]>
models.Article.objects(拿到全部的文章,等同於objects.all).extra(循環Article裏邊的每個對象,給它加一個鍵值,鍵是「is_recent」,值是每個Article對應執行的sql語句,寫ORM的時候歷來沒這麼寫過,這個sql語句會對應每個Article對象進行執行,執行一次統計出來一個結果若是大於了就返回1小於了就返回0;處理完的結果依然是Queryset,不一樣的是每個Article對象多了個屬性叫is_recent)
TruncMonth函數,例子:Sales商品表,按照以前就進行分組統計了,但它並無,timestamp把它理解爲create_time,TruncMonth把它截斷只截到年月,而後賦值給了month字段;跟方式一是同樣的,方式一用date_format來截斷賦給了一個叫y_m_date這樣子一個鍵。Sales裏邊就多加了一個叫month的屬性。.values就至關於Group By month,再annotate統計哪一個字段的數量,再最終顯示month和c值。
views.py
def home_site(request, username, **kwargs): ''' 我的站點視圖函數 :param request: :return: ''' print("username", username) user = UserInfo.objects.filter(username=username).first() # 過濾,判斷是否有這個名字 # 判斷當前用戶是否存在! if not user: return render(request, "not_found.html") # 查詢當前站點對象 blog = user.blog # 當前用戶或者當前站點對應的全部文章 # 基於對象 # article_list = user.article_set.all() # 基於 __ article_list = models.Article.objects.filter(user=user) # 我的站點頁面的標籤與分類查詢
# 每個後的模型.objects.values("pk").annotate(聚合函數(關聯表__統計字段)).values("表模型的所在字段")
# 查詢每個分類名稱以及對應的文章數 ret = models.Category.objects.values("pk").annotate(c=Count("article__title")).values("title", "c") print(ret) # <QuerySet [{'c': 1, 'title': 'AI'}, {'c': 1, 'title': 'SQL'}, {'c': 1, 'title': 'JAVA'}]> # 查詢當前站點的每個分類名稱以及對應的文章數 cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values("title", "c") print(cate_list) # 查詢當前站點的每個標籤名稱以及對應的文章數 tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values("title", "c") print(tag_list) # 我的站點頁面的日期查詢 # 查詢當前站點每個年月的名稱以及對應的文章數 # 新加一個字段的單表查詢;你若是按create_time,它是年月日時分秒,根本無法分類分在一塊兒
# 日期歸檔方式一: # date_list = models.Article.objects.filter(user=user).extra(select={"y_m_date": "date_format(create_time, '%%Y-%%m')"}).values("y_m_date").annotate(c=Count("title")).values("y_m_date", "c") # print(date_list) # 日期歸檔方式二:(導入TruncMonth函數) from django.db.models.functions import TruncMonth date_list = models.Article.objects.filter(user=user).annotate(month=TruncMonth("create_time")).values("month").annotate(c=Count("title")).values("month", "c") print(date_list) # 要把settings裏邊改爲USE_TZ= False;否則會報錯 return render(request, "home_site.html", {"username": username, "blog": blog, "article_list": article_list, "cate_list": cate_list, "tag_list": tag_list, "date_list": date_list})
在我的站點的視圖函數中構建數據--->>傳到home_site模板中進行渲染
home_site.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> <style> *{ margin: 0; padding: 0; } .header{ width: 100%; height: 60px; background-color: #369; } .content .title{ font-size: 18px; font-weight: 100; line-height: 60px; color: white; margin-left: 20px; } .backend{ float: right; color: white; text-decoration: none; font-size: 14px; margin-top: 10px; margin-right: 15px; } .pub_info{ margin-top: 10px; color: darkgrey; } </style> </head> <body> <div class="header"> <div class="content"> <p class="title"> <span>{{ blog.title }}</span> <a href="" class="backend">管理</a> </p> </div> </div> <div class="container"> <div class="row"> <div class="col-md-3"> <div class="panel panel-warning"> <div class="panel-heading">個人標籤</div> <div class="panel-body"> {% for tag in tag_list %} <p><a href="">{{ tag.title }}</a>({{ tag.c }})</p> {% endfor %} </div> </div> <div class="panel panel-danger"> <div class="panel-heading">隨筆分類</div> <div class="panel-body"> {% for cate in cate_list %} <p><a href="">{{ cate.title }}</a>({{ cate.c }})</p> {% endfor %} </div> </div> <div class="panel panel-info"> <div class="panel-heading">隨筆歸檔</div> <div class="panel-body"> {% for date in date_list %} <p><a href="">{{ date.month|date:"Y-m" }}</a>({{ date.c }})</p> {% endfor %} </div> </div> </div> <div class="col-md-9"> <div class="article_list"> {% for article in article_list %} <div class="article_item clearfix"> {# clearfix:清除浮動 #} <h5><a href="">{{ article.title }}</a></h5> <div class="article_desc"> <span class="media-right"> {{ article.desc }} </span> </div> <div class="small pub_info pull-right"> <span>發佈於  {{ article.create_time|date:"Y-m-d H:i" }}</span>   <span class="glyphicon glyphicon-comment"></span><a href="">評論({{ article.comment_count }})</a>   <span class="glyphicon glyphicon-thumbs-up"></span><a href="">點贊({{ article.up_count }})</a> </div> </div> <hr> {% endfor %} </div> </div> </div> </div> </body> </html>
views.py
from django.db.models.functions import TruncMonth date_list = models.Article.objects.filter(user=user).annotate(month=TruncMonth("create_time")).values("month").annotate(c=Count("title")).values("month", "c") print(date_list)
# 視圖層要傳 return render(request, "home_site.html", {"username": username, "blog": blog, "article_list": article_list, "cate_list": cate_list, "tag_list": tag_list, "date_list": date_list})
url.py(路由設置)
# -*- encoding:utf-8 -*- urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), path('index/', views.index), re_path('^$', views.index), # 在首頁不用index也能夠顯示出 path('register/', views.register), path('get_valid_img/', views.get_valid_img), path('logout/', views.logout), # media配置 re_path(r"media/(?P<path>.*)$", serve, {"document_root": settings.MEDIA_ROOT}), # 我的站點url
re_path('^(?P<username>\w+)/$', views.home_site), # \w+:數字和字母 # 我的站點跳轉(標籤,分類,歸檔路由設計)
# 根路徑直接加username,w+包含數字和字母,不包含特殊符號;有名分組;
# .* 傳的時候讓它可以識別出特殊符號 / ,任何符號均可以匹配的參數param組(如2019/02.html)
re_path('^(?P<username>\w+)/(?P<condition>tag|category|archive)/(?P<param>.*)/$', views.home_site), # \w+:數字和字母
]
views.py
def home_site(request, username, **kwargs): # 一個是接收2個參數,一個是接收4個參數;先接收2個,若是再有就放到**kwargs; ''' 我的站點視圖函數 :param request: :return: ''' print("username", username) user = UserInfo.objects.filter(username=username).first() # 判斷當前用戶是否存在! if not user: return render(request, "not_found.html") # 查詢當前站點對象 blog = user.blog # 當前用戶或者當前站點對應的全部文章 # 基於對象 # article_list = user.article_set.all() # 基於 __ article_list = models.Article.objects.filter(user=user) if kwargs: condition = kwargs.get("condition") param = kwargs.get("param") if condition == "category": article_list = article_list.filter(category__title=param) elif condition == "tag": article_list = article_list.filter(tags__title=param) else: year, month = param.split("-") article_list = article_list.filter(create_time__year=year, create_time__month=month)
home_site.html
<div class="container"> <div class="row"> <div class="col-md-3"> <div class="panel panel-warning"> <div class="panel-heading">個人標籤</div> <div class="panel-body"> {% for tag in tag_list %} <p><a href="/{{ username }}/tag/{{ tag.title }}">{{ tag.title }}</a>({{ tag.c }})</p> {% endfor %} </div> </div> <div class="panel panel-danger"> <div class="panel-heading">隨筆分類</div> <div class="panel-body"> {% for cate in cate_list %} <p><a href="/{{ username }}/category/{{ cate.title }}">{{ cate.title }}</a>({{ cate.c }})</p> {% endfor %} </div> </div> <div class="panel panel-info"> <div class="panel-heading">隨筆歸檔</div> <div class="panel-body"> {% for date in date_list %} <p><a href="/{{ username }}/archive/{{ date.month|date:"Y-m" }}">{{ date.month|date:"Y-m" }}</a>({{ date.c }})</p> {% endfor %} </div> </div> </div> <div class="col-md-9"> <div class="article_list"> {% for article in article_list %} <div class="article_item clearfix"> {# clearfix:清除浮動 #} <h5><a href="">{{ article.title }}</a></h5> <div class="article_desc"> <span class="media-right"> {{ article.desc }} </span> </div> <div class="small pub_info pull-right"> <span>發佈於  {{ article.create_time|date:"Y-m-d H:i" }}</span>   <span class="glyphicon glyphicon-comment"></span><a href="">評論({{ article.comment_count }})</a>   <span class="glyphicon glyphicon-thumbs-up"></span><a href="">點贊({{ article.up_count }})</a> </div> </div> <hr> {% endfor %} </div> </div> </div> </div>