一、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("{{ user_dict }}{{ user_dict.username }}{{ user_dict.password }}
") user_dict = Context({'user_dict': {'username': 'yafeng', 'password': 123}}) res = temp.render(user_dict) return HttpResponse(res)
"""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(基于类的视图)的基本使用
这里就得要介绍下两种名词,我们知道视图函数并不一定就是函数,也可以是类,所以就有下面的两种写法
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() ]
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("{{ user_dict }}{{ user_dict.username }}{{ user_dict.password }}
") 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方法')
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<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>
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) #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) ]
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("{{ user_dict }}{{ user_dict.username }}{{ user_dict.password }}
") 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页面
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<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>
- 效果图
七、模板语法之过滤器
过滤器其实就是一堆方法,有以下几种:
过滤器:|
语法:
左边的会当做过滤器的第一个参数 | 过滤器名字右边的会当做第二个参数
| length 求数据长
| add 加法运算
| default 默认值(判断值是否为空)
| truncatewords 截取单词(可指定截取个数 三个点不算在内)
| truncatechars 截取字符(可指定截取个数 三个点算在内)
| filesizeformat 文件大小
| slice 切片
| date 日期格式化(time模块不可以,datatime可以被格式化)
| safe 取消转义(告诉浏览器我是安全的值得信赖)
前后端取消转义
前端
| safe
后端
from django.utils.safestring import mark_safe
比如:mark_safe('
我是安全滴
')总结(转义的优点):
前端代码就不一定非得在前端页面书写,可以在后端下好然后传递给前端使用,这样你就可以利用到后端更多的逻辑语法
-代码演示
"""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) ]
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<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>
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("{{ user_dict }}{{ user_dict.username }}{{ user_dict.password }}
") 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 = "你好啊
" bbb = [] res1 = "" res2 = mark_safe("你好啊
") # # 给模板传递数据方式一(自己手动传) # return render(request, 'index.html', {'n':n, 'f':f,.....}) # # 给模板传递数据第二种方式 return render(request, 'index.html', locals()) # locals()会将当前名称空间中所有的变量名全部传递给html页面
- 效果图
八、模板语法之标签
模板语法的符号:
{ { } } 变量相关
{% %} 逻辑相关
那么模板语法的标签其实就是(逻辑相关)
1、for循环的内置对象forloop的原理解析
2、for循环
{% for foo in l %} {% 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循环之with起别名
<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) ]
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("{{ user_dict }}{{ user_dict.username }}{{ user_dict.password }}
") 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 = "你好啊
" bbb = [] res1 = "" res2 = mark_safe("你好啊
") # # 给模板传递数据方式一(自己手动传) # return render(request, 'index.html', {'n':n, 'f':f,.....}) # # 给模板传递数据第二种方式 return render(request, 'index.html', locals()) # locals()会将当前名称空间中所有的变量名全部传递给html页面
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<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 %} #}
{# {% 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>
九、自定义过滤器、标签、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页面的一些内容
# 自定义inclusion_tag @register.inclusion_tag('demo.html', name='myin') def index1(n): l = [] for i in range(n): l.append(i) # 将列表传递给demo.html # return locals() return {'l':l}
<p>自定义inclusion_tag的使用p> {% load mytag %} {% myin 5 %} body> html>
<ul> {% for foo in l %} <li>{{ foo }}li> {% endfor %} ul>
6、总结
在前端页面上使用自定义的过滤器,标签,inclusion_tag都要统一先导入
{% load 你自定义的py文件名(比如mytag) %}
"""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) ]
from django.template import Library register = Library() # 自定义过滤器 @register.filter(name='my_sum') def index(a, b): # 过滤器最多最多接收两个参数 return a + b # 自定义标签 @register.simple_tag(name='my_baby') def xxx(a, b, c, d): return '%s?%s?%s?%s'%(a,b,c,d) # 自定义inclusion_tag @register.inclusion_tag('demo.html', name='myin') def index1(n): l = [] for i in range(n): l.append(i) # 将列表传递给demo.html # return locals() return {'l':l}
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<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 %} #}
{# {% 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 %}#}
{#<p>自定义过滤器的使用p>#}
{#{% load mytag %} {# 字使用自定义过滤器之前得先把他导入过来#}
{#<p>{{ 10|my_sum:90 }}p> {# 自定义过滤器的使用{{ }} #}
{##}
{#<p>自定义标签的使用p> {# 自定义标签的使用{% %} #}
{#{% load mytag %}#}
{#<p>{% my_baby 1 2 3 'hello baby' %}p>#}
{#<p>自定义的过滤器可以在逻辑语句中而自定义的标签不可以p>#}
{#{% if 10|my_sum:100 %}#}
{# <p>条件成立p>#}
{#{% endif %}#}
{#{% if my_baby 1 2 3 4 %}#}
{# <p>条件成立p>#}
{#{% endif %}#}
<p>自定义inclusion_tag的使用p>
{% load mytag %}
{% myin 5 %}
body>
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("{{ user_dict }}{{ user_dict.username }}{{ user_dict.password }}
") 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 = "你好啊
" bbb = [] res1 = "" res2 = mark_safe("你好啊
") # # 给模板传递数据方式一(自己手动传) # return render(request, 'index.html', {'n':n, 'f':f,.....}) # # 给模板传递数据第二种方式 return render(request, 'index.html', locals()) # locals()会将当前名称空间中所有的变量名全部传递给html页面
<ul> {% for foo in l %} <li>{{ foo }}li> {% endfor %} ul>
十、模板的继承
某一各页面大部分区域都是公用的,那这个页面就可以当做模板页面
当别人继承这个页面之后 如何修改这个对应的区域
先在模板页面上通过block实现划定区域
{% block content %} # block后面加你的别名
模板页面内容
{% endblock %}
子页面中先导入整个模板
{% extends '模板页面.html'%} ##模板的继承
修改特定的区域 通过事先划定好的区域名称
{% block content %}
子页面内容
{% endblock %}
通常情况下,模板页面上应该有三块区域
{% block css %}
模板页面内容
{% endblock %}
{% block content %}
模板页面内容
{% endblock %}
{% block js %}
模板页面内容
{% endblock %}
一般情况下 模板的block快越多 可扩展性越强,,除此之外还支持子页面调用父页面对应区域 的内容 {{ block.super }}
- 代码
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<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>
{% block css %}
{% endblock %}
head>
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigationspan>
<span class="icon-bar">span>
<span class="icon-bar">span>
<span class="icon-bar">span>
button>
<a class="navbar-brand" href="#">Branda>
div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)span>a>li>
<li><a href="#">Linka>li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret">span>a>
<ul class="dropdown-menu">
<li><a href="#">Actiona>li>
<li><a href="#">Another actiona>li>
<li><a href="#">Something else herea>li>
<li role="separator" class="divider">li>
<li><a href="#">Separated linka>li>
<li role="separator" class="divider">li>
<li><a href="#">One more separated linka>li>
ul>
li>
ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
div>
<button type="submit" class="btn btn-default">Submitbutton>
form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Linka>li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret">span>a>
<ul class="dropdown-menu">
<li><a href="#">Actiona>li>
<li><a href="#">Another actiona>li>
<li><a href="#">Something else herea>li>
<li role="separator" class="divider">li>
<li><a href="#">Separated linka>li>
ul>
li>
ul>
div>
div>
nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<div class="list-group">
<a href="/mdzz/" class="list-group-item active">
首页
a>
<a href="/reg/" class="list-group-item">注册a>
<a href="/loginn/" class="list-group-item">登录a>
<a href="#" class="list-group-item">Porta ac consectetur aca>
<a href="#" class="list-group-item">Vestibulum at erosa>
div>
div>
<div class="col-md-9">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Panel titleh3>
div>
<div class="panel-body">
{% block content %}
<div class="jumbotron">
<h1>Hello, world!h1>
<p>...p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn morea>p>
div>
{% endblock %}
div>
div>
div>
div>
div>
{% block js %}
{% endblock %}
body>
html>
{% extends 'mdzz.html' %} {% block css %} <style> h2 { color: red; } style> {% endblock %} {% block content %} {% include 'left.html' %} <h2 class="text-center">登录页面h2> <form action=""> <p>username: <input type="text" class="form-control"> p> <p>password: <input type="text" class="form-control"> p> <input type="submit" class="btn btn-primary"> form> {{ block.super }} {# 继承引用模板的内容 #} {% endblock %} {% block js %} {# <script>#} {# alert(123)#} {# script>#} {% endblock %}
{% extends 'mdzz.html' %} {# extend把就可以继承mdzz #} {% block css %} <style> h2 { color: green; } style> {% endblock %} {% block content %} <h2 class="text-center">注册页面h2> <form action=""> <p>username: <input type="text" class="form-control"> p> <p>password: <input type="text" class="form-control"> p> <input type="submit" class="btn btn-danger"> form> {{ block.super }} {{ block.super }} {{ block.super }} {{ block.super }} {{ block.super }} {{ block.super }} {{ block.super }} {% endblock %} {% block js %} {# <script>#} {# alert(666)#} {# script>#} {% endblock %}
- 效果图
十一、模板的导入
将HTML页面当做模块使用 哪里需要就导到那里去 通常这个HTML页面都是不完整的
方法:{% include ‘模板.html’ %}
十二、基于django settings源码实现插拔式设计
import os import sys BASE_DIR = os.path.dirname(__file__) sys.path.append(BASE_DIR) if __name__ == '__main__': # 项目启动就应该朝全局的大字典中设置键值对 os.environ['xxx'] = 'conf.settings' from lib.conf import settings print(settings.NAME)
# NAME = '我是暴露给用户的配置文件'
NAME = '我是项目默认的配置文件'
import importlib import os from lib.conf import global_settings class Settings(object): def __init__(self): # 先循环遍历项目默认的全局配置文件 for name in dir(global_settings): # 判断变量名是否是大写 if name.isupper(): # 键值对设置给对象 k = name # NAME v = getattr(global_settings, name) # yafeng setattr(self, k, v) # 先获取暴露给用户的配置文件的字符串路径 module_path = os.environ.get('xxx') # conf.settings # 里面importlib模块 导入settings文件 md = importlib.import_module(module_path) # md = settings for name in dir(md): # 判断变量名是否是大写 if name.isupper(): # 键值对设置给对象 k = name # NAME v = getattr(md, name) # yafeng setattr(self, k, v) settings = Settings()
- 演示