搭建博客笔记:py_kouga (八) 分类与归档

编写视图函数

  1. filter 就是过滤嘛,相当于 where了。
  2. created_time__year 后面这是双下划线,表示 year 是created_time 的一个属性
blog/views.py

def archives(request, year, month):
    post_list = Post.objects.filter(created_time__year=year,
                                    created_time__month=month
                                    ).order_by('-created_time')
    return render(request, 'blog/index.html', context={'post_list': post_list})

配置URL

正则表达式写路由地址时分组命名,分组匹配的结果就可以传导到视图函数中。

url(r'^archives/(?P[0-9]{4})/(?P[0-9]{1,2})/$', views.archive, name='archive'),

配置模板

官方文档 中提到,{% url 'blog:archive' date.year date.month %} 的做法是为去除模板中硬编码。archive 是 url 中的name,blog 是app名称。有了这两个指向,即便后面视图函数的名称发生变化,也不需要需改模板。——如果编程时长比较长的话,那么你肯定有较多修改函数名的经历。

                

归档

{% archives as date_list %}

遇到的问题:归档文章为空。

1. 查看orm 执行的sql。查询语句加 .query 就可以直接查看

post_list = Post.objects.filter(created_time__year=year,
                                    created_time__month=month
                                    ).order_by('-created_time')
print(post_list.query)

打印出来的 sql 语句:

SELECT `blog_post`.`id`, `blog_post`.`title`, `blog_post`.`body`, `blog_post`.`created_time`, 

`blog_post`.`modified_time`, `blog_post`.`excerpt`, `blog_post`.`category_id`, `blog_post`.`author_id` 

FROM `blog_post` WHERE (EXTRACT(MONTH FROM CONVERT_TZ(`blog_post`.`created_time`, 

'UTC', CST)) = 10 AND `blog_post`.`created_time` BETWEEN 2017-12-31 16:00:00 AND 2018-12-31 
15:59:59.999999) ORDER BY `blog_post`.`created_time` DESC

2. convert_tz

convert_tz 是 Mysql 中用来转化时区的。把 UTC 时区转为当前时区:

select convert_tz(now(), "UTC", "GMT");

因为 settings.py 中写的 USE_TZ = True,在这种情况下 Django 存入数据库的时间都是 UTC 时间,也就是会把我们本地时间减去 8 再存。这也是为什么打印出来的 Sql 里面会调用 convert_tz。但是令我费解的是,一般 UTC 转化为本地时间,使用上面的sql 中的 GMT 就好了,不知道为啥 Django 用的CST 而且还没加引号... 这样的sql 根本无法直接执行的.....

3. extract

教程,http://www.w3school.com.cn/sql/func_extract.asp
extract 是用来日期中单独的部分,如年月日等,语法extract(unit from month)。实例:

select extract(month from convert_tz(now(), "UTC", "GMT"))=10;

查看当前的月份是不是 10,如果等于10返回1,否则返回0.

这样就基本看懂了打印出来的sql了。

4 数据库中关于时区的设置

show variables like "%time_zone%"; 

显示:

 Variable_name    | Value  |
+------------------+--------+
| system_time_zone | CST    |
| time_zone        | system |

time_zone 说明 mysql 使用是 system 的时区,system_time_zone 说明 system 使用的 CST 时区。CST:中国标准时间(China Standard Time)

5 修改时区

我看了些资料,上面建议直接把 mysql 的数据库设置为东八区比较好。于是设置:

vim /etc/mysql/mysql.cnf

[mysqld]
default-time-zone='+08:00'

重启数据库,/etc/init.d/mysql restart, 查看了一下确实改了。

然后我在数据库里执行

select convert_tz(now(), "UTC", "GMT");

发现返回 null,于是发现需要设置一下,见教程

mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root --force -p mysql

6 USE_TZ = False

我做了如上配置之后,但是还是选不出归档文章。看教程下面的评论设置 USE_TZ = False,也就是不使用 UTC 时间,直接采用本地时间进行保存。这样虽然能选出归档文章了,但是数据前后就一致了,之前的文章是 UTC 格式的,但是现在存入文章都是本地时间。

而且 Django 文档中是不建议采用本地时间进行保存的。在我工作中,因为数据库保存的是本地时间,当程序国际化时保存本地时间就出现了问题。虽然这个博客走不到国际化的那一步,但是我觉得使用 UTC 存储时间还是有必要的。

不能执行的关键点是 CST,为什么 CST 不加引号,直接执行这个 sql

你可能感兴趣的:(搭建博客笔记:py_kouga (八) 分类与归档)