Demo Django_todolist

项目内容

在Django基础项目(ToDoList)的基础上完成以下功能:
1、实现一个中间件,该中间件可以检测到用户浏览器版本信息,如果用户使用的浏览器低于IE9则显示用户升级浏览器的页面,否则不能访问和使用到ToDoList的功能
2、在添加的待办事项里面增加一个发布时间,设计一个过滤器,可以格式化时间显示效果。(显示成发布于1小时前,1天前,1周前,1月前,1年前这样的效果。)

参考文档

代码地址:Spareibs的Github

具体实现

定义一个判断用户源的中间件

这里定义了一个判断用户源的中间件【middleware.py】,这里有一个小bug:判断来源可以不全

from django.http import HttpResponse


class CheckSoureMiddware(object):
    def process_request(self, request):
        from_source = request.META['HTTP_USER_AGENT']
        print('from_source ', from_source)
        if 'MSIE 6.0' in from_source:
            request.session['from_source'] = 'MSIE 6.0'
            return HttpResponse('''
升级浏览器
''') if 'Trident/7.0' in from_source: request.session['from_source'] = 'MSIE 7.0' return HttpResponse('''
升级浏览器
''') if 'Trident/7.0' in from_source: request.session['from_source'] = 'MSIE 8.0' return HttpResponse('''
升级浏览器
''') else: request.session['from_source'] = 'pc'

将中间件注册

MIDDLEWARE_CLASSES = [
    'todolist.middleware.CheckSoureMiddware',
]

定义一个格式化时间的过滤器

修改数据库相关字段

修改储存时间字段【models.py】

from django.db import models
import django.utils.timezone as timezone

# Create your models here.
class Todolist(models.Model):
    add_date = models.DateTimeField()

同步更新数据库【manage.py】

(env_py35_django) D:\MaiZi_Edu\Dropbox\Maizi\Django_up\django_homework_end>python manage.py makemigrations
Migrations for 'todolist':
  0003_todolist_add_date.py:
    - Add field add_date to todolist

(env_py35_django) D:\MaiZi_Edu\Dropbox\Maizi\Django_up\django_homework_end>python manage.py migrate
Operations to perform:
  Apply all migrations: sessions, admin, contenttypes, todolist, auth
Running migrations:
  Rendering model states... DONE
  Applying todolist.0003_todolist_add_date... OK

修改html文件,加入时间显示【todolist.html】

{{ todolist_list.body }} --- {{todolist_list.add_date }}

创建poll_filter.py文件并使用

使用if和else实现【poll_filter_old.py】

# coding: utf-8
# author: spareribs

from django import template
import time
import datetime
from dateutil.relativedelta import relativedelta

register = template.Library()


# 将 datetime obj 转换成 timestamp
def date_to_timestamp(date_time):
    return time.mktime(date_time.timetuple())


def time_before():
    timestamp_before = {
        # 1分钟前的时间戳
        'a_minute_before': '',
        # 1小时前的时间戳
        'a_hour_before': '',
        # 1天前的时间戳
        'a_day_before': '',
        # 1周前的时间戳
        'a_week_before': '',
        # 1个月的时间戳
        'a_month_before': '',
        # 1年的时间戳
        'a_year_before': '',
    }
    # 获取当前时间
    now = datetime.datetime.now()
    # 得到1个分钟前的时间(datetim obj)
    timestamp_before['a_minute_before'] = now + relativedelta(minutes=-1)
    # 得到1个小时前的时间(datetim obj)
    timestamp_before['a_hour_before'] = now + relativedelta(hours=-1)
    # 得到1天前的时间(datetim obj)
    timestamp_before['a_day_before'] = now + relativedelta(days=-1)
    # 得到1周前的时间(datetim obj)
    timestamp_before['a_week_before'] = now + relativedelta(weeks=-1)
    # 得到1个月前的时间(datetim obj)
    timestamp_before['a_month_before'] = now + relativedelta(months=-1)
    # 得到1年前的时间(datetim obj)
    timestamp_before['a_year_before'] = now + relativedelta(years=-1)
    # 将datetim obj转换成 timestamp
    for time_tag in timestamp_before:
        timestamp_before[time_tag] = date_to_timestamp(timestamp_before[time_tag])
    return timestamp_before


@register.filter()
def format_date(value):
    before = time_before()
    add_date = date_to_timestamp(value)
    if before['a_minute_before'] < add_date:
        print(before['a_minute_before'], add_date)
        time_ = int(61 - (add_date - before['a_minute_before']))
        return "{0}秒前发布".format(time_)

    elif before['a_hour_before'] < add_date:
        print(before['a_hour_before'], add_date)
        time_ = int(61 - (add_date - before['a_hour_before']) / 60)
        return "{0}分钟前发布".format(time_)

    elif before['a_day_before'] < add_date:
        print(before['a_day_before'], add_date)
        time_ = int(25 - (add_date - before['a_day_before']) / 3600)
        return "{0}小时前发布".format(time_)

    elif before['a_week_before'] < add_date:
        print(before['a_week_before'], add_date)
        time_ = int(8 - (add_date - before['a_week_before']) / 86400)
        return "{0}天前发布".format(time_)

    elif before['a_month_before'] < add_date:
        print(before['a_month_before'], add_date, before['a_month_before'])
        time_ = int(5 - (add_date - before['a_month_before']) / 604800)
        return "{0}周前发布".format(time_)

    elif before['a_year_before'] < add_date:
        print(before['a_year_before'], add_date)
        time_ = int(13 - (add_date - before['a_year_before']) / 2592000)
        return "{0}个月前发布".format(time_)
    else:
        print(before, add_date)
        return "1年前发布"

更简单的方法实现【poll_filter.py】

# coding: utf-8
# author: spareribs
from django import template
import datetime

register = template.Library()

@register.filter()
def time_before(d):
    chunks = (
        (60 * 60 * 24 * 365, u'年'),
        (60 * 60 * 24 * 30, u'月'),
        (60 * 60 * 24 * 7, u'周'),
        (60 * 60 * 24, u'天'),
        (60 * 60, u'小时'),
        (60, u'分钟'),
        (1, u'秒'),
    )

    # 如果不是datetime类型转换后与datetime比较
    if not isinstance(d, datetime.datetime):
        d = datetime.datetime(d.year, d.month, d.day)
    now = datetime.datetime.now()
    delta = now - d
    print(delta)
    # 忽略毫秒
    before = delta.days * 24 * 60 * 60 + delta.seconds
    # 刚刚过去的1分钟
    if before <= 3:
        return u'刚刚'
    for seconds, unit in chunks:
        count = before // seconds
        if count != 0:
            break
    return str(count) + str(unit) + u"前发布"

修改前端,格式化时间

主要的内容如下【todolist.html】

{% load poll_filter %}

{{ todolist_list.body }} --- {{ todolist_list.add_date | time_before }}

遇到的问题

遇到数据库存储时间对应不上的问题

修改了配置文件这两个参数

# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'
# USE_TZ = True
USE_TZ = False

中间件HttpResponse问题

本来想在中间件加个重定向的HttpResponseRedirect,发现不能用。
HttpResponse不会再执行其他任何中间件
其实这个应该在前端使用js来判断更为合适

你可能感兴趣的:(Demo Django_todolist)