Django---MTV和MVC的了解,Django的模版语言变量和逻辑,常见的模
Django---MTV和MVC的了解,Django的模版语言变量和逻辑,常见的模板语言过滤器,自定义过滤器,CSRF了解,Django的母版(继承extends,块block,组件include,静态文件的加载load static),自定义simple_tag和inclusion_tag一丶MTV和MVC???????MTV和MVC是一种软件架构,实现功能一样 MTV:在Django框架中使用??????Model(模型):负责业务对象与数据库的对象(ORM) ??????Template(模版):负责如何把页面展示给用户 ??????View(视图):负责业务逻辑,并在适当的时候调用Model和Template 此外,Django还有一个urls分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template MVC:软件开发规范??????MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller),具有耦合性低、重用性高、生命周期成本低等优点。 ???????M: model 模型 操作数据库 ???????V: view 视图 展示页面 HTML ???????C: controller 控制器 调度 业务逻辑 二丶常用语法????在Django框架模板中存在两种特殊的标记: ??????{{ 变量 }} : 表示获取变量的值 ???????{% 逻辑 %} : 表示逻辑相关操作 变量:???????{{ 变量 }},由字母和下划线组成. ??????. (点) 在模版语言中有特殊的意义,可获取对象的属性值,也可调用对象的方法. # def index(request): res = { # 传数字 'num': 123,# 传字符串 'string1': '中文字符','string2': 'abcd',# 传列表 'lis': ['熊大','熊二','熊三'],# 传字典 'dic': {'name': '张哥','age': 33},# 传对象 'p1': Person('Pig',32) } return render(request,'index.html',res) # html页面 <h1>使用 { {变量} } 展示数据</h1> <p>{{ num }}</p> <p>{{ string1 }}</p> <p>{{ string2 }}</p> # <!--支持.的形式根据索引进行取值--> <p>{{ string2.0 }}</p> <p>{{ lis }}</p> # <!-- 列表也支持.的形式根据索引进行取值 --> <p>{{ lis.1 }}</p> # <!--支持字典的所有方法,不需要加(),也支持.的形式取键对应的值--> <p>{{ dic }}</p> <p>{{ dic.name }}</p> <p>{{ dic.keys }}</p> <p>{{ dic.values }}</p> # <!--对象单独的是内存地址,--> <p>{{ p1 }}</p> # <!--对象的属性--> <p>{{ p1.name }}</p> <p>{{ p1.age }}</p> # <!--对象的方法,不需要加()--> <p>{{ p1.talk }}</p> # <!--若变量不存在,不会报错,得到是一个空的字符串.--> <p>{{ xxx }}</p> #PS: 当模板系统遇到一个(.)时,会按照如下的顺序去查询: 1.在字典中查询 2.属性或者方法 3.数字索引 {# .操作只能调用不带参数的方法 #} {{ person_list.0.dream }} Filter过滤器:???????Django提供过滤器,对展示的字符串进一步筛选 ??????语法: {{ value|filter_name:参数 }} ??????? 注意: ‘:‘左右没有空格,出现空格就报错 ### default 默认 # 语法:{{ value|default:"nothing"}} # value的值没有传递,或者为空类型/None时,都会调用default默认值 # 一旦settings配置文件设置了:TEMPLATES的OPTIONS可以增加一个选项:string_if_invalid:'找不到',可以替代default的的作用. # ps:调用string_if_invalid的优先级高于default,如果设置的变量不存在,调用string_if_invalid对应的值 <p> {{ xxx|default:'aaa' }} </p> ### filesizeformat 格式化数据大小(例如 '13 KB','4.1 MB','102 bytes',最大到PB) # 语法:{{ value|filesizeformat }} <p> {{ 1024|filesizeformat }} #1.0 KB </p> ### add 给变量做 +法,也具有拼接效果. 字符串拼接数字,列表拼接列表 # 语法:{{ value|add:"2" }} <p> {{ num|add:"2" }} # num=10 加2--->12 </p> <p> {{ lis|add:lis}} #列表拼接 </p> <p> {{ string1|add:'123456'}} # 字符串拼接数字 </p> ### lower 大写 # 语法:{{ value|lower }} <p> {{ string2|lower }} </p> ### upper 大写 # 语法: {{ value|upper}} <p> {{ string2|upper }} </p> ### title 标题,首字母大写 # 语法:{{ value|title }} <p> {{ string2|title }} </p> ### ljust 左对齐,rjust 右对齐,center 居中 #语法: "{{ value|ljust:"10" }}" "{{ value|rjust:"10" }}" "{{ value|center:"15" }}" <p> "{{ string1|ljust:"10" }}" <br> "{{ string1|rjust:"10" }}" <br> "{{ string1|center:"1" }}" </p> ### length 获取数据的长度 # 语法: {{ value|length }} <P> {{ string1|length }} </P> ### slice 切片,支持正向 也支持反向 # 语法:{{value|slice:"2:-1"}} <p> {{ lis }} {{ lis|slice:'0:2' }} # 切除来两个 {{ lis|slice:'-1::-1' }} # 反向切出来所有 </p> ### first 取第一个元素 # 语法: {{ value|first }} <p> {{ string1 }} {{ string1|first }} # 取第一个元素 </p> ### last 取最后一个元素 # 语法: {{ value|last }} <p> {{ string1 }} {{ string1|last }} # 取第一个元素 </p> ### join 字符串拼接列表 # 语法: {{ value|join:" // " }} <p> {{ lis|join:'^^' }} </p> ### truncatechars 字符串字符多于指定的字符数量,会被截断。截断的字符串将以省略号(“...”)结尾. # 参数:截断的字符个数 # 语法:{{ value|truncatechars:9}} <p> {{ '难念的经爱上空间的撒谎加括号大数据库很快就打'|truncatechars:10 }} # 字符分隔 </p> <p> {{ '难念的 经爱上 空间的 撒谎加括 号大数据库很快就打'|truncatewords:3 }} #空格分隔,</p> ### date 日期格式化 # 语法: {{ value|date:"Y-m-d H:i:s"}} <p> {{ now|date:'Y-m-d H:i:s' }} # 2019-08-28 15:45:50 </p> # 当在settings配置文件设置以下参数时,就会更改默认时间显示的格式.就可以达到和date一样的效果 USE_L10N = False DATETIME_FORMAT = 'Y-m-d H:i:s' <p> {{ now }} </p> ### safe 告诉django不需要转义 # 文字叙述:?? Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。 # 语法:{{ value|safe }} 'jjss':'<script> for (var i=0 ;i<5;i++){alert("123")}</script>' {{ jjss|safe }} # 告诉浏览器这是安全的代码 {{ jjss }} # Django这个代码当做字符串处理 <script> for (var i=0 ;i<5;i++){alert("123")}</script> # 或者使用mark_save()方法 from django.utils.safestring import mark_safe 'jjss':mark_safe('<script> for (var i=0 ;i<5;i++){alert("123")}</script>') 自定义过滤器:???????1.在app目录下创建一个名为:templatetags的包 ? ???????2.自定义函数 # -*-coding:utf-8-*- # Author:Ds from django import template # register=template.Library() # 注册,名字必须是register @register.filter # 装饰器.这个函数编程一个过滤函数 def my_upper(value,arg=None): return value.upper() @register.filter def my_sum(value,arg=None): print(value,type(value)) if type(value)==str: value=value+str(arg) elif type(value)==int: value=int(value)+arg return value @register.filter(name="addSB") # name属性代表重新命名 def add_sb(value): return "{} SB".format(value) ???????3.在模版页面使用 #### 使用流程 # {# 先导入我们自定义filter那个文件 #} # {% load app01_filters %} # {# 使用我们自定义的filter #} # {{ somevariable|fill:"__" }} # {{ d.name|addSB }} # 具体如下:下 <h1>自定义过滤器</h1> <!--加载myTags py文件--> {% load myTags %} {{ string2|my_upper }} <!-- 加法 --> {{ num|my_sum:2 }} <!-- 减法 --> {{ num|my_subtraction:2 }} <!-- 乘法 --> {{ num|my_multiplication:2 }} <!-- 除法 --> {{ num|my_division:2 }} 模版中的逻辑语法??????模版语言中的for的使用 # for语法: {% for el in el_list %} {{el}} {% endfor %} # for的一些参数 forloop.counter 当前循环的索引值(从1开始) forloop.counter0 当前循环的索引值(从0开始) forloop.revcounter 当前循环的倒序索引值(到1结束) forloop.revcounter0 当前循环的倒序索引值(到0结束) forloop.first 当前循环是不是第一次循环(布尔值) forloop.last 当前循环是不是最后一次循环(布尔值) forloop.parentloop 本层循环的外层循环 ???????for ... empty # for ... empty 语法: {% for el in el_list %} {{el}} {% empty %} # 当循环的东西不存在或者为空时,显示empty的内容 <li>显示为空</li> {% endfor %} ???????if ... elif ... else # 语法: {% if user_list %} 用户人数:{{ user_list|length }} {% elif black_list %} 黑名单数:{{ black_list|length }} {% else %} 没有用户 {% endif %} #PS : 在模板中支持的语法有:and 、or、==、>、<、!=、<=、>=、in、not in、is、is not 不支持连续判断: if a>b>c ### 不支持 不支持算术运算: if 1+2==3 ### 不支持 ???????with 给变量起名字 {% with al=123 %} # 可以直接写一个式子 {{ al }} {% endwith %} {% with al=p1.name %} # 也可以给复杂的变量重 新的简单变量 {{ al }} {% endwith %} {% csrf_token %} 防止跨站请求伪造# 防止跨站请求伪造 <form action="" method="post"> # name="csrfmiddlewaretoken" {% csrf_token %} # 会添加一个隐藏的input框. 当提交数据是,协同csrf令牌一同提交. <input type="text" name="name"> <button>提交</button> </form> 三丶母版???????即定义公共的部分 # base.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>图书管理系统</title> {# 加载静态资源 #} {% load static %} <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}"> <link rel="stylesheet" href="{% static 'css/dashboard.css' %}"> <link rel="icon" href="/static/imgs/QQ图片20190829155013.jpg"> <style> .table > tbody > tr > td,.table > tbody > tr > th,.table > tfoot > tr > td,.table > tfoot > tr > th,.table > thead > tr > td,.table > thead > tr > th { vertical-align: middle; } </style> </head> <body> {# 组件 #} {% include 'nav.html' %} <div class="container-fluid"> <div class="row"> <div class="col-sm-3 col-md-2 sidebar"> <ul class="nav nav-sidebar"> <li class="{% block pub_cls %}{% endblock %}"><a href="/publish_list/">出版社管理 </a></li> <li class="{% block book_cls %}{% endblock %}"><a href="/book_list/">图书管理</a></li> <li class="{% block aut_cls %}{% endblock %}"><a href="/author_list/">作者管理</a></li> </ul> </div> {% block content %} <h1>内容哦</h1> {% endblock %} </div> </div> <script src="{% static 'js/jquery-1.11.1.min.js' %}"></script> <script src="{% static 'js/bootstrap.min.js' %}"></script> <script> {% block js %} {% endblock %} </script> </body> </html> 继承母版???????子页面继承母版,减少代码的重复量 # 语法: {% extends 'base.html'%} # 示例:?? {% extends 'base.html' %} # 继承母版 {% block aut_cls %} active {% endblock %} 块(block)???????子页面继承母版,可以通过block块重新写 # 语法: {% block 变量名%} #内容 {% endblock %} # 示例:?? {% block content %} # 替换母版 content变量 的内容 <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main"> <h2 class="sub-header">作者列表</h2> <div class="table-responsive"> <a href="/author_add/" class="btn btn-info btn-sm">添加作者</a> <table class="table table-striped table-hover"> <thead> <tr> <th>#</th> <th>序号</th> <th>作者ID</th> <th>作者姓名</th> <th>著作</th> <th>操作</th> </tr> </thead> <tbody> {% for author in all_author %} <tr> <td> <input type="checkbox"> </td> <td>{{ forloop.counter }}</td> <td>{{ author.pk }}</td> <td>{{ author.username }}</td> <td> {% for book_obj in author.books.all %} << {{ book_obj.bname }}>> {% endfor %} </td> <td> <a class="btn btn-warning btn-sm" href="/author_edit?pk={{ author.pk }}">编辑</a> <a class="btn btn-danger btn-sm" href="/author_del?pk={{ author.pk }}">删除</a> </td> </tr> {% endfor %} </tbody> </table> {% include 'page.html' %} </div> </div> {% endblock %} 组件:??????将一段代码单独放在页面上. # 语法: {% include 'nav.html' %} {% include 'nav.html' %} {% include 'leftmenu.html' %} 静态文件:???????加载静态资源,可以自动去拼接/static/路径,当修改settings文件配置时,load static 始终获取的是你静态资源的‘别名‘. ### 引用静态文件 {% load static %} # 自动寻找到static对应的静态资源. <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}"> <link rel="stylesheet" href="{% static 'css/dashboard.css' %}"> ### 引用js {% load static %} # 自动寻找到static对应的静态资源. <script src="{% static "mytest.js" %}"></script> #'/static/mytest.js' ### 多出引用同一个资源时,可以重新命名. {% load static %} {% static "images/hi.jpg" as myphoto %} <img src="{{ myphoto }}"></img> ??????使用‘get_static_prefix‘ 拼接路径 ## get_static_prefix 获得静态资源的前缀,如:'/static/' {% load static %} <img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" /> # 后续手动拼接路径 ? 自定义simpletag@register.simple_tag def num_my(*args,**kwargs): # 给的参数限制 return '_'.join(args) + "*".join(kwargs.values()) #返回的值是已经处理过的. # 页面使用 {% load my_Tags %} # 加载 my_Tags自定义文件 {% num_my 'a' 'b' 'c' 'd' %} # 参数必须加引号 自定义inclusion_tag???????自定义include组件 @register.inclusion_tag('page.html') # 必须指定一个页面 def page(num): # 参数不限制 ''' num 是页数 :param num: :return: ''' return {'num':range(1,num+1)} # 必须是返回一个字典. 这个字典的参数还是传到page.html页面中使用 ### 页面使用 {% load my_Tags %} # 加载 my_Tags自定义文件 {% page 10 %} # 也会将页面加载出来 ??????inclusion_tag面试题 ### 面试题: 模板中使用{% sqr_list 3 %},生成如下的dropdown list 控件(下拉菜单) key text 1 1的平方是1 2 2的平方是4 3 3的平方是9 请写出sqr_list的实现 ##### my_Tags from django import template register=template.Library() # 注册 @register.inclusion_tag('homework.html') def sqr_list_DEMO(num): data=[f'{i} ---{i}的平方是{i**2}' for i in range(1,num+1)] return {'data':data} #### homework.html 页面 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> {% load static %} <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}"> </head> <body> <div class="dropdown"> <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> Dropdown <span class="caret"></span> </button> <ul class="dropdown-menu" aria-labelledby="dropdownMenu1"> {% for foo in data %} <li><a href="#">{{ foo }}</a></li> {% endfor %} </ul> </div> </body> <script src="{% static 'js/jquery-1.11.1.min.js' %}"></script> <script src="{% static 'js/bootstrap.min.js' %}"></script> </html> ### 展示页面 {% load myTags %} # 加载 mytag文件 {% sqr_list_DEMO 10 %} # 执行 sqr_list_DEMO (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |