zoukankan      html  css  js  c++  java
  • django 之 视图层、模板层

    视图层

    一.视图函数返回的都是一个HttpResponse对象

    render 和 redirect 都是直接或者间接传的

    二.JsonResponse

    下面这个是正常的json的序列化

    views.py 层
    def test1(request):
        user_dict={'username':'jason 顶天立地 ','password':123}
        json_str= json.dumps(user_dict,ensure_ascii= False)###保证中文不会转成bytes
        return HttpResponse(json_str)
    浏览器展示的:
    {"username": "jason 顶天立地 ", "password": 123}
    

    JsonResponse 序列化

    from django.http import JsonResponse
    
    def test1(request):
        user_dict={'username':'jason 顶天立地 ','password':123}
        # json_str= json.dumps(user_dict,ensure_ascii= False)
    
        return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})#后面的这个代表的是保证中文不会转成bytes
    浏览器展示的:
    {"username": "jason 顶天立地 ", "password": 123}
    

    如果序列的不是字典样式

    def test1(request):
        # user_dict={'username':'jason 顶天立地 ','password':123}
        # json_str= json.dumps(user_dict,ensure_ascii= False)
        l1=[1,'磁场强大','人缘极好']
        return JsonResponse(l1,json_dumps_params={'ensure_ascii':False},safe=False)###最后safe为False这个保证非字典 也可以识别
    浏览器展示的:
    [1, "磁场强大", "人缘极好"]
    

    三.form表单的上传

    home.html

    <!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.js"></script>
    </head>
    <body>
    <form action="" method="post"enctype="multipart/form-data">
       username: <input type="text"name="username">
        password: <input type="text" name="password">
        <p><input type="file" name="myfile"></p>
    
        <input type="submit">
    
    </form>
    </body>
    </html>
    

    views.py

    def test1(request):
          if request.method == 'POST':
            print(request.FILES)
            file_obj= request.FILES.get('myfile')
            print(file_obj.name)
            with open(file_obj.name,'wb') as f:
                for line in file_obj:
                    f.write(line)   ###把图片保存起来
        return render(request,'home.html')
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    <MultiValueDict: {'myfile': [<InMemoryUploadedFile: 333.png (image/png)>]}>
    333.png
    
    FILES可以通过这个拿到文件
    
    注意:form表单上传文件
    			1.必须做的事
    				method必须是post
    				enctype必须是formdata
    			2.暂时需要做的 
    				提交post请求需要将中间件里面的一个csrfmiddleware注释掉
    			
    			后端如何获取用户上传的文件
    				file_obj = request.FILES.get('前端input框name属性值')
    				file_obj.name  # 文件名
    				for line in file_obj:
    					print(line)
    				
    				# django中推荐以下写法
    				for chunk in file_obj.chunks():
    					print(chunk)
    	
    

    四.ab_render的原理

    from django.template import Template,Context
    
    def ab_render(request):
        temp=Template('<h1>{{user_dict}}</h1>')
        user_dict = Context({'user_dict':{'username':'jason','password':123}})
        res= temp.render(user_dict)
        return HttpResponse(res)
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    浏览器显示的:
    {'username': 'jason', 'password': 123}
    

    五.FBV 和CBV

    视图函数并一定就是函数 也可以是类

    FBV:基于函数的视图

    CBV:基于类的视图

    下面是CBV的类的视图

    urls

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^ab_render/', views.ab_render),
        url(r'^login/', views.MyLogin.as_view()), #这个是路由与视图函数对应关系相当于url(r'^login/', views.view)
    ]
    

    views

    from django.views import View
    class MyLogin(View):
        def get(self,request):
            return render(request,'login.html')
    
        def post(self,request):
            return HttpResponse('我是类里面post的方法')
    

    login.html

    <!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.js"></script>
    </head>
    <body>
    <form action=""method="post">
        <input type="submit">
    </form>
    
    </body>
    </html>
    

    遇到上面的这个我们需要考虑一下,并且考虑 一些源码的问题

    朝login提交get请求会自动执行MyLogin里面的get方法
    而提交post请求也会自动执行MyLogin里面的post方法
    为什么MyLogin针对不同的请求方法能够自动执行对应的方法

     研究源码的突破口
    		url(r'^login/',views.MyLogin.as_view())
    		猜想
    			as_view要么是类里面定义的普通函数 @staticmethod
    			要么是类里面定义的绑定给类的方法  @classmethod
    		看源码发现是绑定给类的方法
    


    CBV源码(******)
    				MyClass.as_view()
    				# 函数名加括号执行优先级最高
    				@classonlymethod
    				def as_view(...):
    					def view(...):
    						...
    					return view
    				# 变形
    				url(r'^index/',views.view)  # CBV与FBV在路由匹配上本质是一样的
    				
    				def view(...):
    					self = cls(...)  # 生成的是我们自己写的类的对象
    					...
    					return self.dispatch(...)
    					"""
    					当你看到self.属性或方法的时候 不要想当然 
    					一定要遵循对象的属性和方法的查询顺序
    					对象本身  产生对象的类  类的父类
    					"""
    				def dispatch(...):
    					# 先判断当前请求方式是否在默认的八个合法请求方式内
    					if request.method.lower() in ['get','post','delete','options'...]
    						# 利用反射获取对象中对应的属性
    						handler = getattr(self,request.method.lower(),报错信息)
    					
    					return handler(...)  # 执行获取到的方法
    					
    

    FBV和 CBV在路由匹配上本质是一样的,都是路由和函数内存地址的对应关系

    六.importlib

    我们正常的通过模块可以获取模块里面的值

    conf包 里面有b.py
    name= 'david'
    
    a.py
    # from conf import b
    # print(b.name)
    >>>>>>>>>>>>>>>>>>>>
    david
    

    上面的我们可以用其他的importlib来写

    conf包 里面有b.py
    name= 'david'
    
    a.py 
    import importlib
    res= 'conf.b'
    md=importlib.import_module(res)
    #该方法的最小单位是模块 不是模块里面的单个名字
    print(md.name)
    >>>>>>>>>>>>>>>>>>>>
    david
    

    模板层

    一.模板传值

    python基本数据类型全部支持传递给html文件
    		函数
    		类
    			函数和对象会自动加括号
    			# 模板语法不支持传参
    		对象
    			后端给html文件传递数据的两种方式
    			1.指名道姓
    				return render(request,'index.html',{'n':n,'f':f})###放在一个字典里
    
    			2.locals()  # 会将当前名称空间中所有的变量名全部传递给html页面
    				return render(request,'index.html',locals())  
    		
    			html页面上 如何获取到后端传递过来的数据 
    				{{ 变量名 }}
    	
    		取值
    			django模板语法取值 只有一种操作方式  句点符 .
    			点索引
    			点键
    			
    			<p>{{ l.2 }}</p>
    			<p>{{ d.username }}</p>
    			<p>{{ d.password }}</p>
    			<p>{{ d.hobby.1.username.1 }}</p>
    

    8种数据类型和函数 、类 、对象传递给html文件

    views

    def index(request):
        #python的所有的数据类型都支持传递给html页面
        n=11
        f=11.111
        s='hello world'
        l=[1,2,3,4,5,6]
        d={'username':'jason','password':123,'hobby':['read',{'username':['egon','jason']}]}
        t=(1,2,3,4,5,6,)
        se={1,2,3,4,5}
        b= True
        ff= False
        ss='dsdkljgjsg sjg;d  djle dejs;egl dee kd;le;lk '
        sss='是的K歌 警方介入进来大家多 罚款交了比较 房间里人家给 外婆'
        file_size= 3290237579476
        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',locals())
    

    index.html

    <!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 }}</p>#}
    {#<p>{{ MyClass.get_func }}</p>#}
    {#<p>{{ MyClass.get_cls }}</p>#}
    {#<p>{{ MyClass.get_self }}</p>#}
    {#<p>{{ obj }}</p>#}  ##得到的是对象的地址
    {#<p>{{ obj.get_func }}</p>#}
    {#<p>{{ obj.get_self }}</p>#}
    {#<p>{{ obj.get_cls }}</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 :设置默认值 如果是True 返回True  如果是false  返回默认值
    	|truncatechars: 截取字符  后面加3个点
    	|truncatewords:截取单词  后面加3个点
    	|filesizeformat:文件大小 换算成多少B
    	|slice :切片
    	|date:  转化成日期格式
    	|safe:转义  可以把css js等样式渲染到前端
    

    views

    def index(request):
        from datetime import datetime
    
        s= 'hello world dvdlej  vdnelegjn  nej  dje vnle vgjnlew ldeg gel eglkkeg '
        a= 12
        b= True
        ff = False
        file_size= 298355976576
        ddd= datetime.now()
        res= '<h1>你好啊</h1>'
        res1= '<script>alert(123)</script>'
        return render(request,'index.html',locals())
    
    

    index.html

    {#<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>#}
    

    浏览器的显示结果

    70
    
    True、2222ff
    
    he...
    
    hello world dvdlej vdnelegjn nej dje vnle vgjnlew ...
    
    277.9 GB
    
    he
    
    2020年/01月/07日
    
    你好啊
    

    前后端取消转义
    前端
    |safe
    后端
    from django.utils.safestring import mark_safe
    mark_safe('

    安全滴

    ')
    总结:前端代码不一定非要在前端页面写,可以在后端写好传递给前端页面使用
    这样的话 你就可以利用到后端更加多的逻辑语法
    下面是举例

    from django.utils.safestring import mark_safe
    res2= mark_safe('<h1>积极阳光帅气</h1>')
        return render(request,'index.html',locals())
    
    index.html
    <p>{{ res2 }}</p>
    

    三.模板语法逻辑相关

    forloop 对象

    判断for循环的开始结束的位置

    索引 计数

    如下是在html页面上

    {# {% for foo in l %}#}
    {#{{ forloop }}#}
    {# {% endfor %}#}
        
        
        打印的结果是:
        {'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 6, 'revcounter0': 5, 'first': True, 'last': False} {'parentloop': {}, 'counter0': 1, 'counter': 2, 'revcounter': 5, 'revcounter0': 4, 'first': False, 'last': False} {'parentloop': {}, 'counter0': 2, 'counter': 3, 'revcounter': 4, 'revcounter0': 3, 'first': False, 'last': False} {'parentloop': {}, 'counter0': 3, 'counter': 4, 'revcounter': 3, 'revcounter0': 2, 'first': False, 'last': False} {'parentloop': {}, 'counter0': 4, 'counter': 5, 'revcounter': 2, 'revcounter0': 1, 'first': False, 'last': False} {'parentloop': {}, 'counter0': 5, 'counter': 6, 'revcounter': 1, 'revcounter0': 0, 'first': False, 'last': True}
        
        ###第一个是True  最后一个是True
    

    for 循环 if 判断

    views.py 里面的是 l=[1,2,3,4,5,6]
    
    html页面
    {% for foo in l %}
    {% if forloop.first %}
        <p>这是我的第一次</p>
        {% elif forloop.last %}
        <p>这个是最后一次</p>
        {% else %}
        <p>{{ foo }}</p>
    
    {% endif %}
    
    {% endfor %}
    

    浏览器结果

    这是我的第一次
    
    2
    
    3
    
    4
    
    5
    
    这个是最后一次
    

    如果是空的 可以用下面的empty来判断

    views.py 里面的是 l=[]
    
    html页面
    {% for foo in l %}
    {% if forloop.first %}
        <p>这是我的第一次</p>
        {% elif forloop.last %}
        <p>这个是最后一次</p>
        {% else %}
        <p>{{ foo }}</p>
    
    {% endif %}
    {% empty %} {# 这个是用来的判断的 如果容器内没有值#}
        <p>for循环的对象没有值</p>
    {% endfor %}
    

    四.对于多用和常用的可以起个别名

    这个别名只能在with里面使用

    views.py
    def index(request):
    d = {"username": 'jason', 'password': 123, 'hobby': ['read', {'username': ['jason', 'egon']}]}
    return render(request,'index.html',{'l':l,'d':d} )
    
    
    index.html
    {% with d.hobby.1.username.1 as eg %}
        <p>别名{{ eg }}</p>
        
    {% endwith %}
    

    五.自定义的过滤器、标签 、inclusion_tag

    自定义过滤器 标签 inclusion_tag
    先完成以下前期准备工作
    1.在应用名下新建一个名字必须叫templatetags文件夹
    2.在该文件夹内新建一个任意名称的py文件(eg:mytag)
    3.在该文件内 必须先写以下两句代码
    from django.template import Library
    register= Library()

    总结 页面上使用他们 统一先导入

    {% load mytag %}

    mytag.py

    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 index1(a,b,c,d):
        return '%s?%s?%s?%s?'%(a,b,c,d)
    
    
    #自定义inclusion_tag
    @register.inclusion_tag('demo.html',name='myin')
    def index(n):
        l=[]
        for i in range(n):
            l.append(i)
        #将列表传递给demo.html ## 这个return给demo.html在上面@register这个里面
        return {'l':l}
    

    index.html

    <body>
    
    <p>自定义的过滤器</p>
    {% load mytag %}
    <p>{{ 10|my_sum:90 }}</p>
    
    {% if 10|my_sum:100 %}
        <p>条件成立</p>
    
    {% endif %}
    >>>>>>>>>>>>>>>>>>>>>>>
    100
    
    <p>自定义的标签</p>
    {% load mytag %}
    <p>{% my_baby 1 2 3 'hello world' %}</p>
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    1?2?3?hello world?
    
    <p>自定义的inclusion_tag的使用</p>
    {% load mytag %}
    {% myin 5 %}
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    0
    1
    2
    3
    4
    
    </body>
    </html>
    

    demo.html

    <ul>
     {% for foo in l %}
     <li>{{ foo }}</li>
     {% endfor %}
      
    </ul>
    

    六.模板的继承

    ​ 某一个页面大部分区域都是公用的 那这个页面就可以作为模板页面
    ​ 当别人继承这个页面之后 如何修改对应的区域

    先在模板页面上通过block实现划定区域
    {% block content %}	
    模板页面内容
    {% endblock %}
    
    子页面中先导入整个模板
    {% extends '模板页面.html'%}
    修改特定的区域  通过实现划定好的区域名称
    {% block content %}
    子页面内容
    {% endblock %}
    
    通常情况下 模板页面页面应该起码有三块区域
    {% block css %}	
    模板页面内容
    {% endblock %}
    {% block content %}	
    模板页面内容
    {% endblock %}
    {% block js %}	
    模板页面内容
    {% endblock %}
    # 模板的block块越多 可扩展性越高
    
    
    
    还支持子页面调用父页面对应区域的内容 并且可以无限次调用
    {{ block.super }}
    

    urls.py

     #模板的导入
        url(r'^mdzz/',views.mdzz),
        url(r'^loginn/',views.loginn),
        url(r'^register/',views.register)
    

    views.py

    def mdzz(request):    return render(request,'mdzz.html')def loginn(request):    return render(request,'loginn.html')def register(request):     return render(request,'register.html')
    

    mdzz.html

    <!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.js"></script>
        {% block css %}
    
        {% endblock %}
    
    </head>
    <body>
    <nav class="navbar navbar-inverse">
      <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <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 navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">Brand</a>
        </div>
    
        <!-- Collect the nav links, forms, and other content for toggling -->
        <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="#">Link</a></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="#">Action</a></li>
                <li><a href="#">Another action</a></li>
                <li><a href="#">Something else here</a></li>
                <li role="separator" class="divider"></li>
                <li><a href="#">Separated link</a></li>
                <li role="separator" class="divider"></li>
                <li><a href="#">One more separated link</a></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">Submit</button>
          </form>
          <ul class="nav navbar-nav navbar-right">
            <li><a href="#">Link</a></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="#">Action</a></li>
                <li><a href="#">Another action</a></li>
                <li><a href="#">Something else here</a></li>
                <li role="separator" class="divider"></li>
                <li><a href="#">Separated link</a></li>
              </ul>
            </li>
          </ul>
        </div><!-- /.navbar-collapse -->
      </div><!-- /.container-fluid -->
    </nav>
    <div class="container-fluid">
    <div calss="row" >
        <div class="col-md-3" >
                <div class="list-group">
                  <a href="/mdzz/" class="list-group-item active">###a标签
                    首页
                  </a>
                  <a href="/register/" class="list-group-item">注册</a>###a标签
                  <a href="/loginn/" class="list-group-item">登录</a>###a标签
                  <a href="#" class="list-group-item">Porta ac consectetur ac</a>
                  <a href="#" class="list-group-item">Vestibulum at eros</a>
    </div>
        </div>
    <div class="col-md-9">
                <div class="panel panel-primary">
              <div class="panel-heading">
                <h3 class="panel-title">Panel title</h3>
              </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 more</a></p>
    </div>
                  {% endblock %}
    
              </div>
    </div>
    </div>
    </div>
    </div>
    
    {% block js %}
    
    {% endblock %}
    
    </body>
    </html>
    

    loggin.html

    {% extends 'mdzz.html' %}
    
    {% block css %}
        <style>
        h2 {
            color:green;
        }
        </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-success">
    
        </form>
        {{ block.super }}
    {% endblock %}
    
    {% block js %}
        <script>
        alert(123)
        </script>
    {% endblock %}
    

    register.html

     {% extends 'mdzz.html' %}
    
    {% block css %}
        <style>
        h2{
            color:red;
        }
        </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>
        <p>
            <input type="submit" class="btn btn-danger">
        </p>
        </form>
    {{ block.super }}
    {{ block.super }}
    {{ block.super }}
    {% endblock %}
    
    {% block js %}
        <script>
        alert(666)
        </script>
    {% endblock %}
    

    七.模板的导入

    将html页面当做模块使用 哪里需要导哪里 这个html页面通常都不是完整的 只是一个局部样式
    {% include '要导入的模块名' %}

    举例

    left.html

    <p>这是我做的很美的一个模块</p>
    

    将left.html模块导入到这个loginn.html中,直接在loginn.htm 要插入的位置放上{% include 'left.html' %} 即可

    八.基于django settings源码实现项目配置文件的 插拔式设计

    conf.settings.py

     NAME='我是暴露给用户的配置文件'
    

    lib.conf.--init--.py

    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
                    v= getattr(global_settings,name)
                    setattr(self,k,v)
    
            #先获取暴露给用户的配置文件的字符串路径
            module_path = os.environ.get('xxx')
            #里面的importlib模块 导入到settings文件
            md= importlib.import_module(module_path)
            #md能拿到settings里面的所有的名字
            #同上操作
            for name in dir(md):
                #判断变量名是否大写
                if name.isupper():
                    #键值对设置给对象
                    k= name
                    v= getattr(md,name)
                    setattr(self,k,v)
    
    settings = Settings()
    

    lib.conf.global_settings.py

    NAME ='我是项目默认的配置文件'
    

    start.py

    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)
    
    

    暴露给用户的配置文件,如果用户的存在 就用用户的, 如果用户的没有 ,就是用全局系统默认的

    django其实有两个配置文件 一个是暴露给用户的可以自定义的配置 一个是项目默认的配置
    		用户如果配置了就用用户的 没有配置就用默认的
    		
    		from django.conf import global_settings,settings
    		
    		settings = LazySettings()
    		
    		
    		class LazySettings(...):
    			def _setup(...):
    				# 获取暴露给用户的配置文件字符串路径
    				setting_module = os.environ.get(纯大写变量名)
    				"""
    				manage.py
    				os.environ.setdefault(纯大写变量名,'暴露给用户的配置文件字符串路径')
    				"""
    				
    				Settings(setting_module)
    		def Settings(...)
    			# 先遍历全局默认的配置文件       给对象设置键值对
    			for setting in dir(global_settings):
    				if setting.isupper():
    					setattr(self,setting,getattr(global_settings,setting))
    					
    			
    			# 再遍历暴露给用户的配置文件     给对象设置键值对
    			md = importlib.import_module(setting_module)
    			for setting in dir(md):
    				if setting.isupper():
    					setattr(self,setting,getattr(md,setting))
    			"""
    			利用的其实就是字典的键存在和不存在 下面语句的作用
    			dict[key] = value
    			"""
    
  • 相关阅读:
    GC原理---垃圾收集算法
    GC原理---对象可达判断
    散列算法和哈希表结构
    桶排序
    Spring事务梳理
    AQS
    重入锁
    CAS
    研究一下phpspider
    用php写爬虫去爬数据
  • 原文地址:https://www.cnblogs.com/bs2019/p/12168576.html
Copyright © 2011-2022 走看看