zoukankan      html  css  js  c++  java
  • django 源码、模板的语法符号的使用

    django 基础

    render 原理

    代码:

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

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

    FBV:基于函数的视图
    CBV:基于类的视图
    

    CBV基本写法

    from django.views import View
    
    
    	class MyLogin(View):
    		def get(self,request):
    			return render(request,'login.html')
    		def post(self,request):
    			return HttpResponse('我是类里面的post方法')
    	
       urls.py
    	url(r'^index/',views.MyClass.as_view())
    	# 针对不同的请求方式 能够自动执行类中不同的方法
    

    CBV源码(******)

    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(...)  # 执行获取到的方法
    

    作用:

    朝着login提交get请求会自动执行Mylogin里面的get方法
    而提交post请求也会自动执行Mylogin里面的post方法
    

    研究源码的突破口

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

    怎么看源码:

    猜想
    	as_view要么是类里面定义的普通函数 @staticmethod
    	要么是类里面定义的绑定给类的方法  @classmethod
    看源码发现是绑定给类的方法
    		
    看源码不需要每一句都看懂  只看自己能够看得懂
    

    步骤如图:

    第一步

    第二步:

    第三步:

    第四步:

    django settings源码

    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
    

    模板的语法符号

    {{}}  变量相关
    {% %}  逻辑相关
    

    模板层之模板传值

    python基本数据类型全部支持传递给html文件
    python所有基本数据类型均可
    

    函数

    模板语法会自动加括号调用 但是不支持传参
    

    函数和对象会自动加括号
    # 模板语法不支持传参
    

    对象

    后端给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>
    

    模板语法之过滤器 |

    关键字的方法:

    |length  :获取数据的长度
    |add    :加法的运算
    |default  :默认值(判断值是否为空)
    |truncatechars :截取字符(截取5个字符 三个点也算)
    |truncatewords :截取单词(截取8个单词 三个点不算)
    |filesizeformat :文件的大小
    |slice      : 切片的操作
    |date       : 日期格式化
    |safe       : 转义
    

    使用方式

    <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>
    

    效果:

    文件大小

    效果:

    前后端取消转义

    前端

    |safe
    

    后端

    from django.utils.safestring import mark_safe
    res2 = mark_safe('<h1>你好啊</h1>')
    可在后端直接使用mark_safe方法 使前端不用加 |safe 都可以直接运行res2
    

    总结:

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

    模板语法之标签 (逻辑相关)

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

    添加描述信息后

    效果:

    1578396787243

    没有相对参数时

    效果:

    for 循环



    效果:

    当一个值获取的步骤非常繁琐 但是又需要在很多地方用到 我们可以用起别名的方式来简化代码

    效果:

    自定义过滤器 标签 inclusion_tag

    先完成以下前期准备工作:

    1.在应用名下新建一个名字必须叫templatetags文件夹
    2.在该文件夹内新建一个任意名称的py文件(eg:mytag)
    3.在该文件内 必须先写以下两句代码
    
    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}
    

    使用方法:

    		<p>自定义过滤器的使用</p>
    		{% load mytag %}
    		<p>{{ 10|my_sum:90 }}</p>
    
    		<p>自定义标签的使用</p>
    		{% load mytag %}
    		<p>{% my_baby 1 2 3 'hello world' %}</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 %}
    		# 总结 页面上使用他们 统一先导入
    			{% load mytag %}
    

    代码:

    <p>自定义过滤器的使用</p>
    	{% load mytag %}
    	<p>{{ 10|my_sum:90 }}</p>
    

    效果:

    代码:

    效果:

    自定义的过滤器可以在逻辑语句中而自定义的标签不可以

    <p>自定义的过滤器可以在逻辑语句中而自定义的标签不可以</p>
    {% if 10|my_sum:100 %}
    <p>条件成立</p>
    {% endif %}
    
    {% if my_baby 1 2 3 4 %}
    <p>条件成立</p>
    {% endif %}
    

    代码:

    # 自定义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}
    

    效果:

    模板的继承

    需求:某一个页面大部分区域都是公用的 那这个页面就可以作为模板页面
    当别人继承这个页面之后 如何修改对应的区域
    
    某一个页面大部分区域都是公用的 那这个页面就可以作为模板页面
    当别人继承这个页面之后 如何修改对应的区域
    		
    先在模板页面上通过block实现划定区域
    	{% block content %}	
    		模板页面内容
    	{% endblock %}
    		
    子页面中先导入整个模板
    	{% extends '模板页面.html'%}
    	修改特定的区域  通过实现划定好的区域名称
    		{% block content %}
    				子页面内容
    		{% endblock %}
    		
    通常情况下 模板页面页面应该起码有三块区域
    		{% block css %}	
    			模板页面内容
    		{% endblock %}
    		{% block content %}	
    			模板页面内容
    		{% endblock %}
    		{% block js %}	
    			模板页面内容
    		{% endblock %}
    	# 模板的block块越多 可扩展性越高
    		
    	还支持子页面调用父页面对应区域的内容 并且可以无限次调用
    			{{ block.super }}
    		
    

    先在模板页面上通过block实现划定区域

    先去视图层建立 views.py

    def mdzz(request):
        return render(request,'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.min.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 class="row">
            <div class="col-md-3">
                <div class="list-group">
                  <a href="/mdzz/" class="list-group-item active">
                    首页
                  </a>
                  <a href="/register/" class="list-group-item">注册</a>
                  <a href="/loginn/" class="list-group-item">登录</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>
    

    子页面中先导入整个模板

    登录页面

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

    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 %}
    

    1578402104426

    通常情况下 模板页面页面应该起码有三块区域

    注册页面

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

    html文件代码:

    {% extends 'mdzz.html' %}
    
    {% 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 %}
    

    1578402182198

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

  • 相关阅读:
    一道简单的递推题(快速幂+矩阵乘法优化+滚动数组)
    玲珑OJ 1129
    (转)Python函数式编程——map()、reduce()
    在windows中安装两个不同版本的Python
    Python 安装 pytesser 处理验证码出现的问题
    Python爬虫之HDU提交数据
    Python SGMLParser 的1个BUG??
    CF622F:The Sum of the k-th Powers
    LuoGuP3321:[SDOI2015]序列统计
    卡马克开方膜拜笔记
  • 原文地址:https://www.cnblogs.com/WQ577098649/p/12163756.html
Copyright © 2011-2022 走看看