2021年3月26日星期五

🍖Django框架之模板层

一.两种模板方法

  • 变量相关 : {{ }}

  • 逻辑相关 : {% %}

二.注释

  • 注释是代码之母 : {# #}

三.模板语法之传值

1.Python中基本数据类型传值

def test_func(request): s = "Hello 派大星!" i = 1314520 f = 1.75 l = [1,2,3,4,5] d = {"name":"shawn","age":23} t = (2,3,4,5,5) se = {3,4,5,'rr'} b = True  # 传值方式一 : 使用字典的格式一个个传 return render(request,'test.html',{'strs':s,'ints':i,'lists':l,...}) # 传值方式二 : 使用 locals()将当前名称空间所有的变量名全部传递微页面 return render(request,'test.html',locals())
  • test.html 文件
<h1>{{ s }}</h1><h1>{{ i }}</h1><h1>{{ f }}</h1><h1>{{ l }}</h1><h1>{{ d }}</h1><h1>{{ t }}</h1><h1>{{ se }}</h1><h1>{{ b }}</h1>

image-20210318194630391

2.函数与类的传递

def test_func(request): def aa():  print("aa--->")  return 'I am aa' class Bar(object):  def cc(self):   print("Bar-->cc") B1 = Bar() return render(request, 'test.html', locals())
  • 模板层
<h1>{{ aa }}</h1><h1>{{ Bar }}</h1><h1>{{ B1 }}</h1>

image-20210318194502925

3.函数名与类名注意点

  • 传递函数名与类名都会自动加括号调用
  • 传入函数名得到的结果是函数的返回值
  • 模板语法不支持额外的传参,也就是函数无法传参

4.传值方式优缺点 :

  • 传值方式一 : 传值精确, 不会造成资源浪费
  • 传值方式二 : 传值简单, 可能造成一定的资源浪费

四.模板语法之获取值

  • django模板语法取值只能采用句点符(.),也就是点

  • 可以根据索引以及键取值,支持多个很多个点........

# views.pydef test_func(request): ll = [1,2,{"name":"shawn","age":23,"hobby":["read","study"]}] return render(request,"test.html",{"ll":ll})# 想要取出爱好read# test.html<h1>{{ ll.2.hobby.0 }}</h1>

image-20210318195629158

五.模板语法之过滤器Filter

1.过滤器说明

  • 类似于Python的内置方法
  • 将竖杠左侧的数据当做第一个参数传给右边的过滤器
  • 语法 : {{ [数据]|过滤器:可选参数 }}
  • 注意 : 竖杠左右两边没有空格
  • 过滤器参数包含空格的话需要使用引号包裹
  • 过滤器最多只能有两个参数

2.常用过滤器使用

  • django中大约60中过滤器,下面只介绍常用过滤器
# views.pydef test_func(request): s = "Hello 派大星!" i = 1314520 f = 1.75 l = [1,2,3,4,5] d = {"name":"shawn","age":23} t = (2,3,4,5,5) se = {3,4,5,'rr'} b = True w = 'aa bb cc dd ee ff' return render(request,'test.html',locals())
<!-- test.html--><p>统计长度:{{ s|length }}</p><!-- add数字相加,字符拼接--><p>加法运算:{{ i|add:1000 }}</p><p>字符串拼接:{{ s|add:'Hello 海绵宝宝' }}</p><p>拼接:{{ s|join:'@' }}</p><p>切片:{{ l|slice:'0:5:2' }}</p><p>日期格式:{{ ctime|date:'Y年-m月-d日 H时:i分:s秒' }}</p><!-- 如果第一个参数的布尔值是true则显示左边的值,否则显示default后的值--><p>默认值:{{ b|default:'哈哈' }}</p> <p>文件大小:{{ file_size|filesizeformat }}</p><!-- 截取内容包含三个点,并且算在字符个数之内-->><p>截取文本:{{ w|truncatechars:6 }}</p><!-- 截取内容包含三个点,但不算在单词个数之内,单词识别是以空格来区分的--><p>截取单词:{{ w|truncatewords:3 }}</p>

image-20210326223226444

3.转意

  • 后端使用转意
from django.utils.safestring import mark_safehtml_safe = mark_safe('<h1>你好</h1>')
  • 前端使用转意
{{ html|safe }}

六.模板语法之标签

类似于Python中的流程控制

1.for循环

{% for i in l %} <p>{{ forloop }}</p> <p>{{ i }}</p> # 循环从列表 l 中取出一个个元素{% endfor %}

我们再看看 forloop 输出的是什么:

image-20210318214321276

2.if 判断

# i = 90{% if i > 100 %} <p>is True</p>{% elif i > 80 %} <p>is two</p>{% else %} <p>is no</p>{% endif %}

image-20210318215255704

3.for 与 if 混合使用

{% for i in l %} {% if forloop.first %}  <p>is first</p> {% elif forloop.last %}  <p>is last</p> {% else %}  <p>{{ i }}</p> {% endif %}{% endfor %}

image-20210318215606748

4.empty : 空

{% for foo in request %} {% empty %}  <p>传入的数据为空,无法进行循环</p>{% endfor %}

image-20210318215938511

5.with : 取别名

{% with ll.2.hobby.0 as hb %} <p>{{ hb }}</p>    # 可以使用别名取值 <p>{{ ll.2.hobby.0 }}</p> # 也可以使用原来的方式取值{% endwith %}

image-20210318220320333

6.字典values、keys、items方法

{% for k in d.keys %} <p>{{ k }}</p>{% endfor %}{% for v in d.values %} <p>{{ v }}</p>{% endfor %}{% for kv in d.items %} <p>{{ kv }}</p>{% endfor %}

七.自定义过滤器、标签、inclusion_tag

类似于Python中的自定义函数

1.创建 templatetags 文件

  • 首先在应用下创建一个名字必须叫"templatetags"文件夹
  • 在改文件夹下创建一个任意名称的 py 文件 (例 : mytag)
  • 在该 py 文件内固定书写两行代码
from django import templateregister = template.Library()

2.自定义过滤器

  • 自定义过滤器最多只能有两个形参
from .templatetags.mytag import register# 在模板层导入自定义的过滤器时使用的是这里指定的名字@register.filter(name='myfilter') def sums(a, b): # 函数名随便起什么 return a + b # 返回两个参数的和
{% load mytag %} # 导入tag文件<p>{{ i|myfilter:100 }}</p> # 使用myfilter过滤器

image-20210318225017009

3.自定义标签

  • 自定义标签可以有多个参数
from .templatetags.mytag import register# 在模板层导入自定义的标签时使用的是这里指定的名字@register.simple_tag(name="my_tag")def my_join(a,b,c,d):   # 函数名任意 return f'{a}/{b}/{c}/{d}' # 返回参数拼接后的结果
{% load mytag %} # 导入tag文件<p>{% my_tag 'hello' 'pai' 'da' 'xing' %}</p> # 标签之后的多个参数彼此之间用空格隔开

image-20210318230441986

  • 示例二
from .templatetags.mytag import register# 在模板层导入自定义的标签时使用的是这里指定的名字@register.simple_tag(name="my_tag")def my_join(a,b):   # 函数名任意 return a+b    # 返回和
{% load mytag %}<p>{% my_tag i 100 %}</p>

image-20210318231336629

4.自定义 inclusion_tag

  • inclusion_tag 的内部原理:
  • 在HTML页面中导入写好的 inclusion_tag 并调用了
  • 触发了py文件中一个函数的执行并产生结果
  • 产生的结果通过模板语法传递给一个HTML页面进行渲染
  • 渲染完毕后又返回调用 inclusion_tag 的位置
  • 示例
from .templatetags.mytag import register@register.inclusion_tag('test.html',name='my_incl_tag') # 第一个参数是需要渲染的HTML页面def func(n): data=[] for i in range(n):  data.append(f'第{i}页') return locals()
# test.html 文件{% load mytag %}<p>{% my_incl_tag 6 %}</p>
# test2.html{{ data }}{% for foo in data %} {% if forloop.first %}  <p>{{foo}}</p> {% elif forloop.last %}  <p>{{ foo }}</p> {% else %}  <p>{{ foo }}</p> {% endif %}{% endfor %}

test.html 页面中调用了 inclusion_tag----->触发执行了一个函数产生结果并渲染到 test2.html 页面中, 渲染完又返回 test.html 页面

image-20210318235133415

八.模板的导入

类似于后端的模块, 想要什么页面,局部直接导入即可

{% include 'edit.html' %} # 直接在当前HTML文件里面显示 edit.html 文件的内容

九.模板的继承

1.模板继承的使用

  • 模板的继承首先需要选择一个模板页面, 在该页面里面使用 block 划定可以被更改的区域
# 母板页面 'home.html' 文件{% block [区域名称] %}......{% endblock %}
  • 想要继承的页面可以使用 extends 来继承某一个页面
# 子版{% extends 'home.html' %}{% block [区域名称] %}......{% endblock %}

子版继承了模板, 那么子版的整体格式与模板一样, 被 block 划分了的区域可以自己随意更改

2.模板的三个区域

  • 母板在划分区域的时候一般有三个区域
{% block css %} # css区域{% endblock %}{% block content %} # HTML区域{% endblock %}{% block js %} # js区域{% endblock %}

目的是为了让子版具有独立的css、js等,增加扩展性

  • 子版也可以继续使用母版划定了区域内的内容
{{ block.super }}

3.示例

  • 路由层
urlpatterns = [ path('admin/', admin.site.urls), path('home/', views.func), path('index/', views.func2,name='index_name'),]
  • 视图层
def func(request): return render(request,'home.html')def func2(request): return render(request,'index.html')
  • 模板层
# home.html{% block left-body %}<div > <h1>Hello, world!</h1> <p>这里是一个block划分的区域</p> <p><a href="{% url 'index_name' %}" role="button">Learn more</a></p></div>{% endblock %}# index.html{% extends 'home.html' %}{% block left-body %} <div >  <div >  <a href="#" >   <img src="../static/img/11.png" alt="...">  </a>  </div>  <div >   <a href="#" >    <img src="../static/img/11.png" alt="...">   </a>  </div> </div>{% endblock %}
  • home.html 页面

image-20210319153623274

  • index.html 页面

image-20210319153709598

十.小练习

1.需求

  • 增删改查功能

  • 將对用户增删改查的功能使用模板的继承来写

  • 代码除了模板层与之前无太大差别

2.代码实现

  • urls.py 文件
from django.contrib import adminfrom django.urls import path,re_pathfrom app01 import viewsurlpatterns = [ path('admin/', admin.site.urls), path('home/', views.home_func,name='home_name'), re_path('^edit/(\d+)', views.edit_func,name='edit_name'), re_path('^del/(\d+)', views.del_func,name='del_name'), path('insert/', views.insert_func,name='insert_name'),]
  • views.py 文件
def home_func(request): user_obj_list = models.User.objects.all() return render(request,'home.html',locals())def edit_func(request,id): if request.method == "POST":  name = request.POST.get('name')  pwd = request.POST.get('pwd')  age = request.POST.get('age')  models.User.objects.filter(id=id).update(name=name,pwd=pwd,age=age)  return redirect('home_name') user_obj = models.User.objects.filter(id=id).first() return render(request,'edit.html',{'user_obj':user_obj})def del_func(request,id): models.User.objects.filter(id=id).delete() return redirect('home_name')def insert_func(request): if request.method == "POST":  name = request.POST.get('name')  pwd = request.POST.get('pwd')  age = request.POST.get('age')  models.User.objects.create(name=name,pwd=pwd,age=age)  return redirect('home_name') return render(request,'insert.html')
  • 模板层文件
# home.html 文件##[导航栏代码]##[左侧边栏代码]##[右边内容由block划分]{% block left-body %} <div >  <div >   <h1 >用户数据</h1>   <div >    <table >     <thead>     <tr>      <th>编号</th>      <th>姓名</th>      <th>密码</th>      <th>年龄</th>      <th>操作</th>     </tr>     </thead>     <tbody>      {% for user_obj in user_obj_list %}       <tr>        <td>{{ user_obj.id }}</td>        <td>{{ user_obj.name }}</td>        <td>{{ user_obj.pwd }}</td>        <td>{{ user_obj.age }}</td>        <td>         <a href="{% url 'del_name' user_obj.id %}">删除</a>         <a href="{% url 'edit_name' user_obj.id %}">修改</a>        </td>       </tr>      {% endfor %}     </tbody>    </table>   <div >    <form action="{% url 'insert_name' %}" method="get">     <input type="submit" value="新增">    </form>   </div>   </div>  </div> </div>{% endblock %}# edit.html 文件{% extends 'home.html' %}{% block left-body %}<div ><div > <h2 >修改数据</h2> <div >  <form action="" method="post">   username:   <input type="text" name="name" value="{{ user_obj.name }}">   password:   <input type="text" name="pwd" value="{{ user_obj.pwd }}">   age:   <input type="number" name="age" value="{{ user_obj.age }}">   <input type="submit" value="提交" >  </form> </div></div></div>{% endblock %}# insert.html 文件{% extends 'home.html' %}{% block left-body %} <div > <div >  <h2 >插入数据</h2>  <div >   <form action="" method="post">   username:    <input type="text" name="name">   password:    <input type="test" name="pwd">   age:    <input type="number" name="age">    <input type="submit" value="提交" >   </form>  </div> </div> </div>{% endblock %}

image-20210319171604527

image-20210319171632069

image-20210319171716321

image-20210319171748532









原文转载:http://www.shaoqun.com/a/645728.html

跨境电商:https://www.ikjzd.com/

吉祥邮:https://www.ikjzd.com/w/1565

网易考拉海购大促:https://www.ikjzd.com/w/1052


一.两种模板方法变量相关:{{}}逻辑相关:{%%}二.注释注释是代码之母:{##}三.模板语法之传值1.Python中基本数据类型传值deftest_func(request):s="Hello派大星!"i=1314520f=1.75l=[1,2,3,4,5]d={"name":"shawn","age":23}t=
聚贸:https://www.ikjzd.com/w/1305
环球华网:https://www.ikjzd.com/w/1063
sonar:https://www.ikjzd.com/w/215
又有老板被代运营骗了!:https://www.ikjzd.com/home/132152
增加曝光率!亚马逊为自有品牌新推出"Our Brand"标签!:https://www.ikjzd.com/home/107501
社交媒体最佳实践指南,助你提升独立站曝光率:https://www.ikjzd.com/home/108988

没有评论:

发表评论