本文转载自https://blog.csdn.net/xiaogeldx/article/details/87869624

关于自定义

  • 代码布局(自定义的代码放在那里)
    • 某个app特有的
      • app目录下创建templatetags(Python的包)(名字固定的)文件夹
      • 把普通文件夹变成Python的包:在文件夹中加__init__.py
      • 在templatetags文件夹下创建Python模块(py文件)
    • 定义复用
      • 创建一个新的app,将他们定义在新的app中,在INSTALL_APPS注册,然后就可以应用
    • app特有的和复用的只是代码布局(代码所在文件夹)不同,没有什么区别
  • templates存放模板的目录
  • templatetags存放自定义标签及过滤器的目录
    templatetags这个目录名字是固定的,而里面的模块名是自定义的

自定义模板过滤器

  • 模板过滤器本质是函数
  • 有一个或两个参数,返回字符串
    • 第一个参数是传递进来的模板变量
    • 第二个参数是普通的参数,也可以是默认,也可以不要
  • 定义非常简单,就是写一个函数,一个带有一个或两个参数的Python参数:
    • (输入的)变量的值不一定是字符串形式
    • 参数的值可以有一个初始值,或者完全不要这个参数

注册自定义过滤器

  • 注册自定义过滤器有两种方法:
    • 通过django.template.Library的实例的filter方法
      django.template.Library.filter()
      • Library.filter()方法需要两个参数:
        • name 过滤器的名称(一个字符串对象),可以不写,默认使用方法名作为过滤器的名称
        • filter_func(定义的过滤器的函数),一个Python函数(不要把函数名写成字符串)
    • 也可以把register.filter()用做装饰器
      • 可以传name参数,也可以不传
  • 没有声明name参数,Django将使用函数名作为过滤器的名字

使用自定义过滤器

  • 在模板中使用自定义的过滤器
  • 需要使用{% load 模块名 %}标签将我们的自定义的模块加载进来
  • {% load 模块名 %}声明将会载入给定模块名中的标签/过滤器

案例

  • views.py中的index代码:

    def index(request):
    students = [
    {'id':10, 'name': '小哥', 'age': 15, 'gender': 1},
    {'id':33,'name': 'yang', 'age': 15, 'gender': 0},
    {'id':53,'name': 'wen', 'age': 25, 'gender': 0},
    {'id':12,'name': 'long', 'age': 18, 'gender': 1},
    {'id':76,'name': 'na', 'age': 16, 'gender': 0},
    {'id':38,'name': 'yi', 'age': 19, 'gender': 0},
    {'id':48,'name': 'xin', 'age': 17, 'gender': 1},
    ]
    return render(request, 'students/index.html', context={
    'students': students,
    })

  • index.html的demo:

    {% extends 'students/base.html' %}
    {% block title %}学生表{% endblock %}
    {% load static %}
    {% load customer_filters %}
    {% block link %}{% endblock %}
    {% block content %}




    {# 从这里开始替换#}







    {# 如果students为空,则渲染empty下的内容#}
    {% for stu in students %}
    <tr {% if stu.age < 17 %}style="color:blue;"
    {% elif stu.age > 16 and stu.age < 22 %}style="color:red;"
    {% else %}style="color:green;"
    {% endif %}>
    {# forloop.counter获取当前for循环的迭代次数,以1开始#}
    {# 硬编码跳转 #}

    {# forloop.counter0获取当前for循环的迭代次数,以0开始#}
    {# #}
    {# forloop.revcounter获取当前for循环的迭代次数,从大到小#}
    {# #}
    {# forloop.revcounter0获取当前for循环的迭代次数,从大到小,最小为0#}
    {# #}


    {#to_male对应customer_filter.py的@register.filter的name名对应#}


    {# 如果students为空,则渲染empty下的内容#}
    {# {% empty %}#}
    {# 要渲染的内容#}
    {% endfor %}
    序号 姓名 年龄 性别
    {{ forloop.counter }} {{ forloop.counter }}{{ forloop.counter0 }}{{ forloop.revcounter }}{{ forloop.counter0 }} {{ stu.name }} {{ stu.age }} {{ stu.gender|to_male:'en' }}




    {# 将渲染好的模板放到想要放的模板#}
    {% include 'students/ad.html' %}

    {% endblock %}
    {% block domready %}


  • customer_filter.py的demo:

    from django.template import Library
    register = Library()
    # @register.filter() #和下一行的区别是下一行可以定义name名
    #自定义过滤器的第二种方法
    @register.filter(name='to_male') #'to_male'对应{{ stu.gender }}的to_male
    def to_male(value, arg='zh'): #默认是中文
    map = {
    'zh': ('女', '男'),
    'en': ('female', 'male')
    }
    # if value == 0:
    # if arg == 'zh':
    # return '女'
    # return 'female'
    # if value == 1:
    # if arg == 'zh':
    # return '男'
    # return 'male'
    return map[arg][value] #等同于上几行注释掉的demo
    #下面三行注释掉的是一样的效果,是注册自定义过滤器的第一种方法
    # register.filter('to_male', to_male)
    # register.filter(to_male)
    # register.filter(name='to_male', filter_func=to_male)
    效果图:
    ![在这里插入图片描述]( https://img-blog.csdnimg.cn/20190223205959512.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW9nZWxkeA==,size_16,color_FFFFFF,t_70)

自定义模板标签

简单标签

django.template.Labrary.simple_tag()

  • 新建Python模块
    • 在templatetags中创建py文件,customer_tags.py
  • 注册
    • 调用函数
    • 装饰器
  • 引用上下文变量(views中render传递到模板中的那个context)
    • 只需要在simple_tag中,设置参数take_context=True
    • 自定义的标签函数的第一个参数一定是context
  • 使用自定义模板标签
    • 需要使用{% load 模块名 %}标签将我们的自定义的模块加载进来

demo

  • views.py的代码:

    format_str = '%Y-%m-%d %H:%M:%S'
    return render(request, 'students/index.html', context={
    'students': students,
    'format_str': format_str,
    })

  • index.html的代码:

    {% load customer_tags %} #在开头

    当前时间:{% current %}

    #在正文部分

  • customer_tags的代码:

    from django.template import Library
    from datetime import datetime
    register = Library()
    @register.simple_tag(name='current', takes_context=True) #注册,装饰器
    def current_time(context): #context必须是第一个参数,并且名字固定,不能改
    return datetime.now().strftime(context['format_str'])
    # register.simple_tag(current_time, name='current') #注册,调用函数

包含标签

django.template.Library.inclusion_tag()

  • 通过渲染另外一个模板来展示数据,类似url中的include

定义

  • 在customer_tags模板中定义一个函数,接受调用时传递的模板变量

    @register.inclusion_tag('students/show_list_as_ul.html') #参数是想要传的模板
    def show_list_as_ul(value, style):
    return {'ls': value, 'style': style}
    # registerinclusion_tag('students/show_list_as_ul.html')(show_list_as_ul)

  • 定义一个模板

  • tag()方法有两个参数:

    • 模板标记的名称是字符串,如果省略,将使用编译函数的名称
    • 编译的函数是一个Python函数(不要把函数名写成字符串)
    • 和简单标签注册一样,也可以将其用做装饰器
    • 也可以拿到context,和简单标签用法一样
  • 包含标签的功能是可以通过渲染另外一个模板来显示一些数据

  • 很多地方都可能会用到下面这几行代码,除了choices(模板变量)这几个变量不一样之外,其他的都是格式都一样时,那么我们就可以把这部分代码封装在一个包含标签中


      {% for i in choices %}
    • {{ i }}

    • {% endfor %}

案例

  • show_list_as_ul.html的代码:

    {% if style == 'button' %}


    {% for l in ls %}

    {% endfor %}

    {% elif style == 'link' %}

    {% for l in ls %}
    {{ l }}
    {% endfor %}

    {% else %}

      {% for l in ls %}
    • {{ l }}

    • {% endfor %}

  • index.html的部分代码:

    {# {% show_list_as_ul stu.course 'link' %}#}
    {# 等同于上行代码#}
    {# {% show_list_as_ul stu.course style='link' %}#}
    {# {% show_list_as_ul stu.course 'button' %}#}
    {% show_list_as_ul stu.course '' %}

  • customer_tags.py的部分代码:

    @register.inclusion_tag('students/show_list_as_ul.html') #参数是想要传的模板路径
    def show_list_as_ul(value, style):
    return {'ls': value, 'style': style}
    # registerinclusion_tag('students/show_list_as_ul.html')(show_list_as_ul)

posted on 2019-02-23 23:44  小哥东  阅读(225)  评论(0)    收藏  举报