Django基础(32):按日期与时间范围查询数据及模板中日期时间类型数据的格式化和比较

Django基础(32):按日期与时间范围查询数据及模板中日期时间类型数据的格式化和比较

虽然老家湖北的新冠肺炎仍然令人担忧,但我们还是要向前看,不要让太多的焦虑影响我们的生活,毕竟瘟疫很快会过去,而生活还是要继续。小编我今天总结了如何在Django视图与模板中处理日期与时间类型(DateTime)数据, 比如视图中按日期时间查询数据以及在模板中进行日期时间类型数据的格式化与计算。

Django视图中按日期与时间查询数据

假如我们有如下一个Article文章模型,包含有发布日期pub_date这个字段。

class Article(models.Model):
    """Article Model"""
    pub_date = models.DateTimeField('Publish date')

比如我们想查询2020年1月1日以后已发表的文章,我们可以按如下操作。除了等于=,Django对于日期时间类型字段的数据查询还支持gt(greater than,大于), lt (less than,小于), gte (greater than or equal,大于或等于) 及lte(less than or equal,小于或等于),

Article.objects.filter(pub_date__gt=datetime.date(2020, 1, 1))

我们也可以按年份或月份查询2019年发布的全部文章,如下所示。我们只需要在相应字段使用双划线__连接year或month即可。

Article.objects.filter(pub_date__year=2019)

与当前时间进行比较,查询未来发布文章。注意这里没有使用datetime.datetime.now(),这是因为一但你设置了时间,便有一个包含时区的相对时间和一个UTC绝对时间,一般比较最好和timezone的相对时间相比。

from django.utils import timezone
Article.objects.filter(pub_date__gt=timezone.now())

按时间范围查询发表文章

import datetime
article = Aritlce.objects.filter(pub_ate__gte=datetime.date(2020, 1, 1),
pub_date__lte=datetime.date(2020, 1, 31))

按时间范围查询数据,一个更灵活可读性更高的方式是使用range查询方式,定义起始日期和结束日期,如下所示:

import datetime
startdate = datetime.date(2020, 1, 1)
enddate = startdate + datetime.timedelta(days=30)
Article.objects.filter(pub_date__range=[startdate, enddate])

当然使用range方式查询有个小细节值得注意,如果字段本身是date格式,而不是datetime格式,上述查询将不会返回最后一天的数据。

Django模板中日期时间数据格式化

在Django模板中显示日期时间数据格式一定要注意先进行格式化。Y, m, d分别代表年月日,以数字显示。以下方法将显示日期为如' 2020-02-20 '的格式。

<p>{{ pub_date | date:"Y-m-d" }}</p>

如果显示完整时间如 2020-01-20 09:10:30 , 我们可以按如下方式设置。H, i, s分别代表小时,分与秒。

<p>{{ pub_date | date:"Y-m-d H:i:s" }}</p>

如果显示完整时间如 1 Feb 2019 , 我们可以按如下方式设置。j也代表日期,与d的区别在于其前面不加0。M与小写m的区别是其以英文缩写显示月份,而不是数字。另外F也代表月份,为英文月份全称。

<p>{{ pub_date | date:"j M Y" }}</p>

在模板中显示当前时间可以直接使用Django提供的{% now %}标签

It is {% now "Y-m-d Y H:i:s" %}

{% now %}这个标签很有用,比如可以用来更新copyright声明年份。

{% now "Y" as current_year %}
{% with pub_date=article.pub_date %}
    {% if pub_date|date:"YmdHis" > current_date %}
          Not published yet. You cannot view this.
     {% endif %}
 {% endwith %}

我们还需要经常计算pub_date与当前请求时间的间隔,比如2天前,还剩1一个月,我们此时可用django提供的timesince和timeuntil模板过滤器,如下所示:

 {% now "YmdHis" as current_date %}
{% with pub_date=article.pub_date %}