博客五部曲之二 - 高级博客


1271 浏览 5 years, 4 months

20 博客帖子阅读时间

版权声明: 转载请注明出处 http://www.codingsoho.com/

这一节我们会更新get_read_time,并给这个值加一个专门的field TimeField

class Post(models.Model):
#
    read_time = models.TimeField(null=True, blank=True)

同时增加pre_save函数,在保存之前计算这个值并存储

def pre_save_post_receiver(sender, instance, *args, **kwargs):
    if instance.content:
        html_string = instance.get_markdown()
        read_time = get_read_time(html_string)
        instance.read_time = read_time

需要utils里面的get_read_time,时间单位改为分钟,同时计算时间时做了处理, math.ceil会向上取整。

def get_read_time(html_string):
    count = count_words(html_string)
    read_time_min = math.ceil(count/200.0) # assuming 200wpm reading  
    # read_time_sec = read_time_min * 60
    read_time = str(datetime.timedelta(minutes=read_time_min))
    return read_time

在post_detail.html里添加时间显示,这儿对时间显示做了优化。因为时间是如果小于1分钟,则显示为小于一分钟;如果小于十分钟,则显示为小于10分钟,否则它前面会多个0,比如05表示5分钟。这些处理都不够完美,但是基本能解决我们常见的需求。

<p>Readtime : {% if instance.read_time|time:"i" <= "01" %} < 1 minute {% elif instance.read_time|time:"i" < "10" %} < 10 minute {% else %}{{instance.read_time|time:"i"}} minutes{% endif %}</p>

分钟的显示用了time过滤器,参数为i表示分钟,具体参数意义可参考下面链接。
https://docs.djangoproject.com/en/1.11/ref/templates/builtins/#date

在这个例子中,实际上我们可以直接把field设成整形,可以简化操作且能实现相同的功能

假定时间单位为分钟

class Post(models.Model):
    read_time = models.IntegerField(default=0) #TimeField(null=True, blank=True)

修改get_read_time函数,直接返回分钟数即可

def get_read_time(html_string):
    count = count_words(html_string)
    read_time_min = math.ceil(count/200.0) # assuming 200wpm reading  
    # read_time_sec = read_time_min * 60
    # read_time = str(datetime.timedelta(minutes=read_time_min))
    # return read_time
    return int(read_time_min)

在post_detail.html显示的地方修改为

<p>Readtime : {% if instance.read_time < 1 %} < 1 minute {% else %}{{instance.read_time}} minutes{% endif %}</p>