自定义过滤器

  • 步骤
  1. 自定义的模板过滤器必须放在app中,并且这个app必须要在INSTALLED_APPS中进行安装。
  2. 在这个app下面创建一个python包叫做templatetags这个名字是绝对的
  3. 在这个包下创建一个python文件
    • 如果app的名字为book,项目结构为: ```htl
  • book
    • views.py
    • urls.py
    • models.py
    • templatetags
      • my_filter.py ```
  1. 在新建的python文件中定义过滤器
  2. 在新建的python文件中注册该过滤器
  3. 在模板中使用load标签加载过滤器所在的python文件名
  • 实例

    • 先在setting.py中的INSTALLED_APPS安装app

      1. INSTALLED_APPS = [
      2. 'django.contrib.admin',
      3. 'django.contrib.auth',
      4. 'django.contrib.contenttypes',
      5. 'django.contrib.sessions',
      6. 'django.contrib.messages',
      7. 'django.contrib.staticfiles',
      8. "book", # app名
      9. ]
    • 在app下新建一个名为templatetagspython package,并且在这个包内新建一个python文件
      自定义过滤器 - 图1

    • 在这个python文件中定义过滤器和注册该过滤器 ```python

      my_filter.py

from django import template

register = template.Library() # 注册library

注册方法一 使用装饰器

@register.filter

默认使用函数名作为过滤器的名字 如果不想,可以使用@register.filter(“name”)

def link_str(value, arg): # 定义过滤器 return value + arg

注册方法二

register.filter(“link_str”, link_str) # 注册过滤器

  1. - 视图函数传递一个上下文
  2. ```python
  3. # views.py
  4. def style_filter(request):
  5. context = {
  6. "value": "jack",
  7. }
  8. return render(request, "style_filter.html", context=context)
  • 模板中使用自定义的过滤器。注意需要用load标签加载自定义过滤器的文件名。 ```html {# style_filter.html #} {% load my_filter %} {# 使用load标签加载自定义过滤器的文件名 #}

<!DOCTYPE html>

{{ value|link_str:”hello” }}

  1. - 运行
  2. <br />![](https://cdn.nlark.com/yuque/0/2019/png/367873/1559638026272-493ba163-6c44-44e1-92ac-84ee546a3418.png#align=left&display=inline&height=195&originHeight=195&originWidth=289&size=0&status=done&width=289)
  3. <a name="00a95e48"></a>
  4. ### 自定义事件计算过滤器
  5. - 获得一条信息发表的时间。该时间是距离现在多久。比如`刚刚`, `2小时前`等。可以自定义一个过滤器。
  6. - 实例
  7. - 在上面的`my_filter.py`中定义过滤器和注册过滤器
  8. ```python
  9. from django import template
  10. from datetime import datetime
  11. register = template.Library() # 注册library
  12. @register.filter()
  13. def time_since(value):
  14. minute = 60
  15. hour = minute*60
  16. day = hour*34
  17. month = day*31
  18. if not isinstance(value, datetime):
  19. return value
  20. now = datetime.now()
  21. # now-value是一个timedelay类型,有一个total_second()方法
  22. timestamp = (now-value).total_seconds() # 时间戳
  23. if timestamp < minute:
  24. return "刚刚"
  25. elif minute <= timestamp < hour: # 简化链式只适合and
  26. m = int(timestamp/minute) # py3除法有小数
  27. return "{}分钟前".format(m)
  28. elif hour <= timestamp < day:
  29. h = int(timestamp/hour)
  30. return "{}小时前".format(h)
  31. elif day <= timestamp < month:
  32. d = int(timestamp/day)
  33. return "{}天前".format(d)
  34. else:
  35. return value.strftime("%Y/%m/%d %H:%H")
  • urls映射和视图函数 ```python

    urls.py

path(‘time/‘, views.time_filter),

  1. ```python
  2. # views.py
  3. from datetime import datetime
  4. def time_filter(request):
  5. context = {
  6. "value": datetime(year=2018,
  7. month=11, day=4, hour=15, minute=0, second=0),
  8. }
  9. return render(request, "style_filter.html", context=context)
  • 模板 ```html {# style_filter.html #} {% load my_filter %} {# 使用load标签加载自定义过滤器的文件名 #}

<!DOCTYPE html>

{{ value|time_since }}

  1. - 运行
  2. <br />![](https://cdn.nlark.com/yuque/0/2019/png/367873/1559638026168-836529da-5233-4ca8-9746-04849f949b70.png#align=left&display=inline&height=159&originHeight=159&originWidth=278&size=0&status=done&width=278)
  3. <a name="66e131dc"></a>
  4. ### 模板标签和模板过滤器查看
  5. ```python
  6. from django.template import defaultfilters, defaulttags