django源码剖析以及模板语法

一、python 之禅

  用一行就带你体会python的美及简洁

  使用方法:在cmd中输入python然后回车,再输入import this 

 

 二、render 的原理

  render原理其实就是相当于是Template以及Context的结合体,接下来我们就简单的模拟下,那么在使用之前我们需要在views.py中导入这两个模块

  from django.template import Template,Context

注意:前期我们在使用post 请求的时候记得一定要把settings总的MIDDLEWARE下的一个csrf.CsrfViewMiddleware给注释掉

- 演示代码

from django.shortcuts import render, HttpResponse, redirect

# Create your views here.
from django.template import Template, Context
# Django的render原理其实就相当于Template, Context的结合

def ab_render(request):
    temp = Template("<h1>{{ user_dict }}{{ user_dict.username }}{{ user_dict.password }}</h1>")
    user_dict = Context({'user_dict': {'username': 'yafeng', 'password': 123}})
    res = temp.render(user_dict)
    return HttpResponse(res)
Views.py
"""day52 URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^ab_render/', views.ab_render),
]
urls.py

效果图:

 三、CBV(基于类的视图)的基本使用

  这里就得要介绍下两种名词,我们知道视图函数并不一定就是函数,也可以是类,所以就有下面的两种写法

  FBV: 基于函数的视图

  CBV:基于类的视图

1、CBV的基本写法

  from django.views import View

  路由中写法:

  url(r'^login/', views.Mylogin.as_view())  # 注意:一定要在对应的视图函数后面.as_view()

2、代码演示

"""day52 URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^ab_render/', views.ab_render),

    # CBV路由配置
    url(r'^login/', views.Mylogin.as_view())
    # 注意一定要在对应的视图函数后面.as_view()
]
urls.py
from django.shortcuts import render, HttpResponse, redirect

# Create your views here.
from django.template import Template, Context
# Django的render原理其实就相当于Template, Context的结合

def ab_render(request):
    temp = Template("<h1>{{ user_dict }}{{ user_dict.username }}{{ user_dict.password }}</h1>")
    user_dict = Context({'user_dict': {'username': 'yafeng', 'password': 123}})
    res = temp.render(user_dict)
    return HttpResponse(res)



from django.views import View


class Mylogin(View):
    def get(self, request):

        return render(request, 'login.html')

    def post(self, request):

        return HttpResponse('我是类里面的post方法')
Views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>

</head>
<body>
<form action="" method="post">
    <input type="submit">
</form>
</body>
</html>
login.html

3、效果图

 

 四、CBV源码剖析

  通过刚刚的演示,我们可以看到我们朝login提交get请求会自动执行Mylogin里面的get方法,而提交post请求也会自动的执行Mylogin里面的post方法,那么为什么Mylogin可以针对不同的请求方式会自动执行相对应的方法,接下来我们就来研究下Django中的CBV源码剖析

1、研究源码的突破口

  url(r'^login/', views.Mylogin.as_view())

  猜想:

    as_view要么是类里面定义的普通函数 @staticmethod

    要么是类里面定义的绑定给类的方法 @classmethod

  所以接下来我们就点进去as_view看下,结果看源码发现是@classmethod,可以确定是绑定给类的方法

注意:看源码并一定要每一句都能够看懂 只看自己能够看懂的即可

2、演示

 五、Django settings源码剖析

1、用户可以看到的settings

  Django在配置中暴露给用户可以查看的settings源码其实不多,也就100多行,那其实这并不是Django真正的settings源码,其实Django真正的settings源码是另一个叫settings,我们可以在settings中去通过from  djjango.conf import global_settings ,settings前面是查看全局源码, 后面通过django.conf导入的settings是真正的配置文件。

总结:这里有一个结论很重要,用户自己配置了就用用户的,用户没有配置的就用Django默认的,比如之前会默认给我们加一个斜杠/

2、研究Django默认的settings源码的原理

1、点击我们之前从django.conf导入的settings,发现这里有一个单例模式

 2、点击LazySettings

 3、去manage.py中

 4、继续研究LazySettings

 5、点击Settings这个类

 6、得出结论

- importlib补充说明

name = 'yafeng'
# from conf import b
# #
# # print(b.name)

import importlib    # 注意:importlib这个最小识别单位只能到py文件, 不然会报错

# res = 'conf.b.name'  #ModuleNotFoundError: No module named 'conf.b.name'; 'conf.b' is not a package

res = 'conf.b'
md = importlib.import_module(res)

# print(md)   #<module 'conf.b' from 'D:\\python的pycharm\\ab_imp\\conf\\b.py'>

print(md.name)  # yafeng

六、模板语法之传值取值

1、给模板传值的两种方式

  (一)python基本数据类型全部支持传递给前端HTML文件

  1、后端给HTML传值的两种方式

  a:自己手动去传数据(指名道姓)

  return render(request, 'index.html', {'n':n, 'f': f, .....})

  b:locals()会自动将当前名称空间所有的变量名全部传递给html页面

  return render(request, 'index.html', locals())

  2、HTML页面上 如何获取后端传递过来的数据

  {{ 变量名 }}

  (二)函数也可以传递给前端HTML文件

   注意:函数传递给前端的时候会自动加括号执行,在浏览器上展示的是函数的返回值

      但是模板语法并不支持给函数传参,这是限制死的

     (二)类,对象也可以传递给前端HTML文件

    函数和类会自动加括号,并且也可以拥有.的方法

2、取值

  django模板语法取值 只有一种操作方式 句点符. 这个 点可以点索引,点key

- 演示代码

"""day52 URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^ab_render/', views.ab_render),

    # CBV路由配置
    url(r'^login/', views.Mylogin.as_view()),
    # 注意一定要在对应的视图函数后面.as_view()
    # 通过观看源码我们可以得出此时上面的等价于
    # url(r'^login/', views.view)
    # 所以FBV与CBV在路由匹配上本质上是一样的 都是路由与函数内存地质的对应关系


    url(r'^index', views.index)
]
urls.py
from django.shortcuts import render, HttpResponse, redirect

# Create your views here.
from django.template import Template, Context
# Django的render原理其实就相当于Template, Context的结合

def ab_render(request):
    temp = Template("<h1>{{ user_dict }}{{ user_dict.username }}{{ user_dict.password }}</h1>")
    user_dict = Context({'user_dict': {'username': 'yafeng', 'password': 123}})
    res = temp.render(user_dict)
    return HttpResponse(res)



from django.views import View


class Mylogin(View):
    def get(self, request):

        return render(request, 'login.html')

    def post(self, request):

        return HttpResponse('我是类里面的post方法')


import time
from datetime import datetime

from django.utils.safestring import mark_safe
def index(request):

    # python 所有的数据类型都支持传递给html页面
    n = 11
    f = 12.11
    s = 'hello world'
    l = [1,2,3,4,5,6]
    d = {'username': 'yafeng', 'password': 123, 'hobby': ['read', {'username': ['yafeng', 'reba']}]}
    t = (1,2,3,4,5,6,7,)
    se = {1,2,3,4,5,6}
    b = True
    ff = False
    ss = 'kjasdklas ksd;lk  akjsdkl da  kjda k;lak d k;a dk  ska d'
    sss = '卡时间 冻结 鲨科 技的 卡拉 手动 卡萨 丁卡'
    file_size = 32213213424

    def func():
        print('func被执行了')
        return 'from func'


    class MyClass(object):
        def get_self(self):
            return 'from self'


        @staticmethod
        def get_func():
            return 'from func'


        @classmethod
        def get_cls(cls):
            return 'from cls'

    obj = MyClass()

    # # 给模板传递数据方式一(自己手动传)
    # return render(request, 'index.html', {'n':n, 'f':f,.....})
    #
    # 给模板传递数据第二种方式
    return render(request, 'index.html', locals())

    # locals()会将当前名称空间中所有的变量名全部传递给html页面
Views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>

</head>
<body>
{#<p>{{ n }}</p>#}
{# 这种注释是模板语法的注释不会显示到浏览器上 #}
<!--这种注释可以显示-->
{#<p>{{ f }}</p>#}
{#<p>{{ s }}</p>#}
{#<p>{{ l }}</p>#}
{#<p>{{ d }}</p>#}
{#<p>{{ t }}</p>#}
{#<p>{{ se }}</p>#}
{#<p>{{ b }}</p>#}
{#<p>{{ func }}</p>#}

{#<p>传类名也会 自动实例化 {{ MyClass }}</p>#}
{#<p>{{ MyClass.get_self }}</p>#}
{#<p>{{ MyClass.get_cls }}</p>#}
{#<p>{{ MyClass.get_func }}</p>#}
{#<p>{{ obj }}</p>#}
{#<p>{{ obj.get_cls }}</p>#}
{#<p>{{ obj.get_func }}</p>#}
{#<p>{{ obj.get_self }}</p>#}

<p>取值</p>
<p>{{ l.2 }}</p>
<p>{{ d.username }}</p>
<p>{{ d.password }}</p>
<p>{{ d.hobby.1.username.1 }}</p>



</body>
</html>
index.html

- 效果图

 七、模板语法之过滤器

  过滤器其实就是一堆方法,有以下几种:

  过滤器:|

    语法:

      左边的会当做过滤器的第一个参数 | 过滤器名字右边的会当做第二个参数 

    | length        求数据长

    | add           加法运算

    | default        默认值(判断值是否为空)

    | truncatewoords   截取单词(可指定截取个数  三个点不算在内) 

    | truncatechars   截取字符(可指定截取个数  三个点算在内)

    | filesizeformat     文件大小

    | slice              切片

    | date              日期格式化(time模块不可以,datatime可以被格式化)

    | safe              转义(告诉浏览器我是安全的值得信赖)

前后端取消转义

  前端

    | safe

  后端

    from django.utils.safestring import mark_safe

    比如:mark_safe('<h1>我是安全滴</h1>')

总结(转义的优点):

  前端代码就不一定非得在前端页面书写,可以在后端下好然后传递给前端使用,这样你就可以利用到后端更多的逻辑语法

-代码演示

"""day52 URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^ab_render/', views.ab_render),

    # CBV路由配置
    url(r'^login/', views.Mylogin.as_view()),
    # 注意一定要在对应的视图函数后面.as_view()
    # 通过观看源码我们可以得出此时上面的等价于
    # url(r'^login/', views.view)
    # 所以FBV与CBV在路由匹配上本质上是一样的 都是路由与函数内存地质的对应关系


    url(r'^index', views.index)
]
urls.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>

</head>
<body>
{#<p>{{ n }}</p>#}
{# 这种注释是模板语法的注释不会显示到浏览器上 #}
<!--这种注释可以显示-->
{#<p>{{ f }}</p>#}
{#<p>{{ s }}</p>#}
{#<p>{{ l }}</p>#}
{#<p>{{ d }}</p>#}
{#<p>{{ t }}</p>#}
{#<p>{{ se }}</p>#}
{#<p>{{ b }}</p>#}
{#<p>{{ func }}</p>#}

{#<p>传类名也会 自动实例化 {{ MyClass }}</p>#}
{#<p>{{ MyClass.get_self }}</p>#}
{#<p>{{ MyClass.get_cls }}</p>#}
{#<p>{{ MyClass.get_func }}</p>#}
{#<p>{{ obj }}</p>#}
{#<p>{{ obj.get_cls }}</p>#}
{#<p>{{ obj.get_func }}</p>#}
{#<p>{{ obj.get_self }}</p>#}

{#<p>取值</p>#}
{#<p>{{ l.2 }}</p>#}
{#<p>{{ d.username }}</p>#}
{#<p>{{ d.password }}</p>#}
{#<p>{{ d.hobby.1.username.1 }}</p>#}

<p>过滤器</p>
<p>求数据长度:{{ s|length }}</p>
<p>加法运算:{{ n|add:10 }}、{{ s|add:13132 }}、{{ s|add:'DSB' }}</p>
<p>默认值(判断值是否为空):{{ b|default:'这个b布尔值是True' }}、{{ ff|default:'这个ff布尔值是Flase' }}</p>
<p>截取字符(截取5个字符 三个点也算):{{ s|truncatechars:8 }}</p>
<p>截取单词(截取8个单词 三个点不算):{{ ss|truncatewords:8 }}、{{ sss|truncatewords:4 }}</p>
<p>文件大小:{{ file_size|filesizeformat }}</p>
<p>切片操作:{{ s|slice:'0:2' }}、{{ s|slice:"0:8:2" }}</p>
<p>日期格式化:{{ ddd|date:'Y年/m月/d日' }}</p>
<p>转义:{{ res|safe }}、{{ res1 }}、后端直接标识安全:{{ res2 }}</p>

</body>
</html>
index.html
from django.shortcuts import render, HttpResponse, redirect

# Create your views here.
from django.template import Template, Context
# Django的render原理其实就相当于Template, Context的结合

def ab_render(request):
    temp = Template("<h1>{{ user_dict }}{{ user_dict.username }}{{ user_dict.password }}</h1>")
    user_dict = Context({'user_dict': {'username': 'yafeng', 'password': 123}})
    res = temp.render(user_dict)
    return HttpResponse(res)



from django.views import View


class Mylogin(View):
    def get(self, request):

        return render(request, 'login.html')

    def post(self, request):

        return HttpResponse('我是类里面的post方法')


import time
from datetime import datetime

from django.utils.safestring import mark_safe
def index(request):

    # python 所有的数据类型都支持传递给html页面
    n = 11
    f = 12.11
    s = 'hello world'
    l = [1,2,3,4,5,6]
    d = {'username': 'yafeng', 'password': 123, 'hobby': ['read', {'username': ['yafeng', 'reba']}]}
    t = (1,2,3,4,5,6,7,)
    se = {1,2,3,4,5,6}
    b = True
    ff = False
    ss = 'kjasdklas ksd;lk  akjsdkl da  kjda k;lak d k;a dk  ska d'
    sss = '卡时间 冻结 鲨科 技的 卡拉 手动 卡萨 丁卡'
    file_size = 32213213424

    def func():
        print('func被执行了')
        return 'from func'


    class MyClass(object):
        def get_self(self):
            return 'from self'


        @staticmethod
        def get_func():
            return 'from func'


        @classmethod
        def get_cls(cls):
            return 'from cls'

    obj = MyClass()

    ttt = time.time()
    ddd = datetime.now()

    res = "<h1>你好啊</h1>"
    bbb = []
    res1 = "<script>alert(123)</script>"
    res2 = mark_safe("<h1>你好啊</h1>")

    # # 给模板传递数据方式一(自己手动传)
    # return render(request, 'index.html', {'n':n, 'f':f,.....})
    #
    # 给模板传递数据第二种方式
    return render(request, 'index.html', locals())

    # locals()会将当前名称空间中所有的变量名全部传递给html页面
Views.py

- 效果图

 八、模板语法之标签

  模板语法的符号:

    {{  }}   变量相关

    {{  }}   逻辑相关

  那么模板语法的标签其实就是(逻辑相关)

1、for循环的内置对象forloop的原理解析

 2、for循环

{% for foo in l %}  <!--l = [1,2,3,4,5,6]-->
{% if forloop.first %}
<p>这是我的第一次</p>
{% elif forloop.last %}
<p>这是最后一次了啊~</p>
{% else %}
<p>{{ foo }}</p>
{% endif %}
{% empty %}
<p>for循环的对象内部没有值</p>
{% endfor %}

 3、for循环之去字典

{% for foo in d.keys %}
<p>{{ foo }}</p>
{% endfor %}


{% for foo in d.values %}
<p>{{ foo }}</p>
{% endfor %}

{% for foo in d.items %}
<p>{{ foo }}</p>
{% endfor %}

4、for循环之起别名

<p>当一个值获取的步骤非常繁琐 但是又需要在很多地方用到 我们可以用起别名的方式来简化代码</p>
{% with d.hobby.1.username.1 as eg %}
<p>别名只能在with内使用:{{ eg }}</p>
<p>{{ d.hobby.1.username.1 }}</p>
{% endwith %}

"""day52 URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^ab_render/', views.ab_render),

    # CBV路由配置
    url(r'^login/', views.Mylogin.as_view()),
    # 注意一定要在对应的视图函数后面.as_view()
    # 通过观看源码我们可以得出此时上面的等价于
    # url(r'^login/', views.view)
    # 所以FBV与CBV在路由匹配上本质上是一样的 都是路由与函数内存地质的对应关系


    url(r'^index', views.index)
]
urls.py
from django.shortcuts import render, HttpResponse, redirect

# Create your views here.
from django.template import Template, Context
# Django的render原理其实就相当于Template, Context的结合

def ab_render(request):
    temp = Template("<h1>{{ user_dict }}{{ user_dict.username }}{{ user_dict.password }}</h1>")
    user_dict = Context({'user_dict': {'username': 'yafeng', 'password': 123}})
    res = temp.render(user_dict)
    return HttpResponse(res)



from django.views import View


class Mylogin(View):
    def get(self, request):

        return render(request, 'login.html')

    def post(self, request):

        return HttpResponse('我是类里面的post方法')


import time
from datetime import datetime

from django.utils.safestring import mark_safe
def index(request):

    # python 所有的数据类型都支持传递给html页面
    n = 11
    f = 12.11
    s = 'hello world'
    l = [1,2,3,4,5,6]
    d = {'username': 'yafeng', 'password': 123, 'hobby': ['read', {'username': ['yafeng', 'reba']}]}
    t = (1,2,3,4,5,6,7,)
    se = {1,2,3,4,5,6}
    b = True
    ff = False
    ss = 'kjasdklas ksd;lk  akjsdkl da  kjda k;lak d k;a dk  ska d'
    sss = '卡时间 冻结 鲨科 技的 卡拉 手动 卡萨 丁卡'
    file_size = 32213213424

    def func():
        print('func被执行了')
        return 'from func'


    class MyClass(object):
        def get_self(self):
            return 'from self'


        @staticmethod
        def get_func():
            return 'from func'


        @classmethod
        def get_cls(cls):
            return 'from cls'

    obj = MyClass()

    ttt = time.time()
    ddd = datetime.now()

    res = "<h1>你好啊</h1>"
    bbb = []
    res1 = "<script>alert(123)</script>"
    res2 = mark_safe("<h1>你好啊</h1>")

    # # 给模板传递数据方式一(自己手动传)
    # return render(request, 'index.html', {'n':n, 'f':f,.....})
    #
    # 给模板传递数据第二种方式
    return render(request, 'index.html', locals())

    # locals()会将当前名称空间中所有的变量名全部传递给html页面
Views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>

</head>
<body>
{#<p>{{ n }}</p>#}
{# 这种注释是模板语法的注释不会显示到浏览器上 #}
<!--这种注释可以显示-->
{#<p>{{ f }}</p>#}
{#<p>{{ s }}</p>#}
{#<p>{{ l }}</p>#}
{#<p>{{ d }}</p>#}
{#<p>{{ t }}</p>#}
{#<p>{{ se }}</p>#}
{#<p>{{ b }}</p>#}
{#<p>{{ func }}</p>#}

{#<p>传类名也会 自动实例化 {{ MyClass }}</p>#}
{#<p>{{ MyClass.get_self }}</p>#}
{#<p>{{ MyClass.get_cls }}</p>#}
{#<p>{{ MyClass.get_func }}</p>#}
{#<p>{{ obj }}</p>#}
{#<p>{{ obj.get_cls }}</p>#}
{#<p>{{ obj.get_func }}</p>#}
{#<p>{{ obj.get_self }}</p>#}

{#<p>取值</p>#}
{#<p>{{ l.2 }}</p>#}
{#<p>{{ d.username }}</p>#}
{#<p>{{ d.password }}</p>#}
{#<p>{{ d.hobby.1.username.1 }}</p>#}

{#<p>过滤器</p>#}
{#<p>求数据长度:{{ s|length }}</p>#}
{#<p>加法运算:{{ n|add:10 }}、{{ s|add:13132 }}、{{ s|add:'DSB' }}</p>#}
{#<p>默认值(判断值是否为空):{{ b|default:'这个b布尔值是True' }}、{{ ff|default:'这个ff布尔值是Flase' }}</p>#}
{#<p>截取字符(截取5个字符 三个点也算):{{ s|truncatechars:8 }}</p>#}
{#<p>截取单词(截取8个单词 三个点不算):{{ ss|truncatewords:8 }}、{{ sss|truncatewords:4 }}</p>#}
{#<p>文件大小:{{ file_size|filesizeformat }}</p>#}
{#<p>切片操作:{{ s|slice:'0:2' }}、{{ s|slice:"0:8:2" }}</p>#}
{#<p>日期格式化:{{ ddd|date:'Y年/m月/d日' }}</p>#}
{#<p>转义:{{ res|safe }}、{{ res1 }}、后端直接标识安全:{{ res2 }}</p>#}

<p>标签</p>
{#{% for foo in l %}#}
{#    <p>{{ forloop }}</p>  {# forloop是for循环内置的对象 #}
{#{% endfor %}#}

{#{% for foo in l %}  <!--l = [1,2,3,4,5,6]-->#}
{#    {% if forloop.first %}#}
{#        <p>这是我的第一次</p>#}
{#    {% elif forloop.last %}#}
{#        <p>这是最后一次了啊~</p>#}
{#    {% else %}#}
{#        <p>{{ foo }}</p>#}
{#    {% endif %}#}
{#    {% empty %}#}
{#        <p>for循环的对象内部没有值</p>#}
{##}
{#    #}
{#{% endfor %}#}

{% for foo in d.keys %}
    <p>{{ foo }}</p>
{% endfor %}


{% for foo in d.values %}
    <p>{{ foo }}</p>
{% endfor %}

{% for foo in d.items %}
    <p>{{ foo }}</p>
{% endfor %}

<p>当一个值获取的步骤非常繁琐 但是又需要在很多地方用到 我们可以用起别名的方式来简化代码</p>
{% with  d.hobby.1.username.1 as eg  %}
    <p>别名只能在with内使用:{{ eg }}</p>
    <p>{{ d.hobby.1.username.1 }}</p>
{% endwith %}

</body>
</html>
index.html

九、自定义过滤器、标签、inclusion_tag

1、前期准备工作

  1、在应用名下新建一个名字必须叫做templatetags文件夹

  2、在该文件夹内新建一个任意名称的py文件

  3、在该py文件内 必须要先写以下两行代码

    from django.template import Library

    register = Library()

 

2、自定义过滤器

from django.template import Library

register = Library()


# 自定义过滤器
@register.filter(name='my_sum')
def index(a, b):   # 过滤器最多最多接收两个参数
    return a + b
<p>自定义过滤器的使用</p>
{% load mytag %}      {# 字使用自定义过滤器之前得先把他导入过来 
<p>{{ 10|my_sum:90 }}</p>   {# 自定义过滤器的使用{{  }} #}

演示

 3、自定义标签

# 自定义标签
@register.simple_tag(name='my_baby')
def xxx(a, b, c, d):
     return '%s?%s?%s?%s'%(a,b,c,d)
<p>自定义标签的使用</p>    {# 自定义标签的使用{%  %} #}
{% load mytag %}
<p>{% my_baby 1 2 3 'hello baby' %}</p>

演示

4、自定义过滤器与自定义标签的区别

1、自定义过滤器用{{ }},而自定义标签用{% %}

2、自定义过滤器可以在罗家语句比如if中而自定义的标签不可以

5、自定义inclusion_tag

  调用inclusion_tag 是作用到HTML页面上,可以通过传参数让他帮你渲染到某一片区域

然后放到页面的某一个位置,可以通过参数动态的改变HTML页面的一些内容

 

猜你喜欢

转载自www.cnblogs.com/yafeng666/p/12163889.html
今日推荐