zoukankan      html  css  js  c++  java
  • Django补充之模板语言

    路由系统

    Django页面详情以及分页

    举个例子:

    有一组后台数据,需要展示到页面上,但由于数据量较大,那就需要做分页了吧,那么怎么才能将页面详情和分页都融合进去呢,Django里的路由系统加上正则表达式可以满足:

    项目中的views.py,需要注意的是要传入页面的参数:

    USER_LIST=[]
    
    for item in range(94):
        temp = {"id":item,"username":'alex'+str(item),"email":'alexemail'+str(item)}
        USER_LIST.append(temp)
    
    #传入第几页的参数
    def index(request,page):
        page=int(page)
        start=(page-1)*10
        end=page*10
        user_list=USER_LIST[start:end]
        return render(request,'index.html',{"user_list":user_list})
    
    #传入数据库中ID的参数,方便指定具体的数据
    def detail(request,nid):
        nid=int(nid)
        current_user_dict=USER_LIST[nid]
        return render(request,'detail.html',{'current_user_dict':current_user_dict})
    
    

    项目中的urls.py:

    from django.contrib import admin
    
    from django.conf.urls import url, include
    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^index/(d+)', views.index),
        url(r'^detail/(d+)', views.detail),
    
    ]
    

    tempaltes中页面:

    index.html :

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
        <table>
            <tr>
                <td>ID</td>
                <td>用户名</td>
                <td>详细</td>
            </tr>
            {% for item in user_list %}
            <tr>
                <td>{{ item.id }}</td>
                <td>{{ item.username }}</td>
                <td><a href="/detail/{{ item.id }}/">查看详情</a></td>
            </tr>
            {% endfor %}
        </table>
    
    </body>
    </html>
    

    detail.html :

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>detail</title>
    </head>
    <body>
        <ul>
            <li>{{ current_user_dict.id }}</li>
            <li>{{ current_user_dict.username }}</li>
            <li>{{ current_user_dict.email }}</li>
        </ul>
    
    </body>
    </html>
    

    urls.py 动态关系

    django中的路由还支持正则表达式和正则表达式的分组,可以这么搞,很多时候用来处理分页和一些URL分配,看下例子:

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^detail/(d+)/', views.detail),
        url(r'^detail2/(d+)/(d+)/', views.detail2),
        url(r'^detail3/(?P<p1>d+)/(?P<x2>d+)/', views.detail3),
     
    ]
    

    这里需要重点说明一点:urls.py中路径的"/"可加可不加,如不加,页面访问时Django会自动加根号处理

    views.py 中的配置:

    
    def detail(request,id):
        print(id)
        return HttpResponse('ok')
    
    
    
    def detail2(request,nid,nnid):
        print(nid,nnid)
        return HttpResponse('ok')
    
    def detail3(request,p1,x2):
        print(p1,x2)
        return HttpResponse('ok')
    

    配置时需要注意后面带上参数,否则会报错.

    路由分组:include导入配置文件

    如果项目APP较多,为了合理分配,我们可以使用分组的概念,urls.py中的include.

    比如,我们有APP叫app01,app02,app03,但为了更好的区分管理各个应用中的url,我们引入include,但首先,需要导入此模块:

    from django.conf.urls import url, include
    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
    #配置下面,利用web区分其他其他应用,名称随便改
        url(r'^web/', include('app01.urls')),
    ]
    

    然后在app01目录中创建urls.py文件:

    from django.conf.urls import url
    from django.contrib import admin
    
    from django.conf.urls import url
    from app01 import views
    urlpatterns = [
        url(r'^template', views.template),
        url(r'^assets', views.assets),
        url(r'^userinfo', views.userinfo),
        url(r'^ajax_demo', views.ajax_demo),
    ]
    

    模板

    模板的渲染

    Django中的模板语言比较简洁,能在浏览器中看到比较复杂的页面,就因为有渲染,源码如下:

    模板 渲染

    模板语言

    模板的语言比较多:

    {{ item }}
    
    {% for item in item_list %}  <a>{{ item }}</a>  {% endfor %}
      forloop.counter
      forloop.first
      forloop.last 
      
    {% if ordered_warranty %}  {% else %} {% endif %}
    
    母板:{% block title %}{% endblock %}
    子板:{% extends "base.html" %}
       {% block title %}{% endblock %}
       
    帮助方法:
    {{ item.event_start|date:"Y-m-d H:i:s"}}
    {{ bio|truncatewords:"30" }}
    {{ my_list|first|upper }}
    {{ name|lower }}
    

    看个例子:

    {{ k1 }}
        {{ k2.1 }}
        {{ k3.name }}
    
        {% for item in k2 %}
            <p>{{ item }},{{ forloop.counter }},{{ forloop.counter0 }},{{ forloop.first }},{{ forloop.last }},{{ forloop.revcounter }}</p>
        {% endfor %}
    
        {% if k1 == 'v1' %}
            <h1>V1</h1>
        {% elif k1 == 'v2' %}
            <h1>V2</h1>
        {% else %}
            <h1>7777</h1>
        {% endif %}
        {{ k1 }}
        {{ k1|lower }}
        {{ k1|f1:"alex,123" }}
        {% f2 1 2 3 4 %}
    
        {% if k1|f3 %}
        <h1>True</h1>
        {% else %}
        <h1>False</h1>
        {% endif %}
    

    模板语言中的索引

    但需要注意的是,索引取值时候,是按照.来取值的:

    一个列表:li=[11,22,33,44,55]
    取列表中的索引为第三的元素:li.2
    
    一个字典:dict={'a':1,'b':2,}
    取列表中的元素:dict.a
    

    模板语言中循环中的forloop

    在模板中的for循环中,有一个forloop语言:

      forloop.counter 取列表中元素对应的索引值,从1开始
      forloop.first   判断是否是循环的第一个,对应值为True,False
      forloop.last 		判断是否循环中的最后一个元素
      forloop,counter0 取列表中元素对应的索引值,从0开始
      forloop.revcounter 取列表中元素对应的索引值,但是反序列的,从最后一个开始
    

    看下例子吧:

    test.html 文件:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>test_template_lanauge</title>
    </head>
    <body>
        {% for item in li %}
            <p>{{ item }},{{ forloop.counter }},{{ forloop.counter0 }},
                {{ forloop.first }},{{ forloop.last }},{{ forloop.revcounter }}</p>
    {#        <p>{{ forloop.counter }}</p>#}
    {#        <p>{{ forloop.counte0 }}</p>#}
    {#        <p>{{ forloop.revcounter }}</p>#}
        {% endfor %}
    </body>
    </html>
    

    views.py 中的数据:

    def test(request):
        li = ['alex','cc','dd','abc','123','sdfs','sdfsf','sdfsdf']
        return render(request,'test.html',{'li':li})
    

    页面中的显示内容:

    alex,1,0, True,False,8
    
    cc,2,1, False,False,7
    
    dd,3,2, False,False,6
    
    abc,4,3, False,False,5
    
    123,5,4, False,False,4
    
    sdfs,6,5, False,False,3
    
    sdfsf,7,6, False,False,2
    
    sdfsdf,8,7, False,True,1
    
    

    模板中的判断语句

    这个比较简单了:

       {% if k1|f3 %}
        <h1>True</h1>
        {% else %}
        <h1>False</h1>
        {% endif %}
    

    更多内置方法

    {{ item.event_start|date:"Y-m-d H:i:s"}}
    {{ bio|truncatewords:"30" }}
    {{ my_list|first|upper }}
    {{ name|lower }}
    

    自定义方法

    自定义方法有两种:simple_tagfilter

    自定义方法 参数限制 是否支持if判断语句
    filter 有限制,只能传入1个,但可以通过字符串然后split来解决 支持if判断语句
    simple-tag 参数无限制 不支持if判断语句

    自定义方法步骤:

    1. 在项目目录下创建指定文件,名称不能改:templatetags

    2. 在templatetags目录中创建任意py文件,比如xx.py,代码如下:

      			
      from django import template
      from django.utils.safestring import mark_safe
      
      #此行如有问题,可以删除
      #from django.template.base import resolve_variable, Node, TemplateSyntaxError
      # 必须不变
      register = template.Library()
      
      # 创建函数
      @register.filter
      def f1(value):
      	return value + "666"
      	
      @register.simple_tag
      def f2(s1,s2,s3,s4):
          return s1+s2+s3+s4
      
      
    3. html页面头部导入

      {%  load xx %}
      
    4. 在HTML页面中使用自定义方法:

      {% load xx %}
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>Title</title>
      </head>
      <body>
          {% if k1|f3 %}
          <h1>True</h1>
          {% else %}
          <h1>False</h1>
          {% endif %}
      
      </body>
      </html>
      
    5. 在setting.py 中注册app

      INSTALLED_APPS = [
      'django.contrib.admin',
      'django.contrib.auth',
      'django.contrib.contenttypes',
      'django.contrib.sessions',
      'django.contrib.messages',
      'django.contrib.staticfiles',
      'app01',
      ]
      

    模板的继承

    母板:

    balabala...
    				
    {% block 名称 %} {% endblock %}
    	
    balabala...
    

    子板,需要声明:{% extends '母板html文件名' %}:

    {% extends '母板html文件名' %}
    	
    	
    {% block 名称 %} 
    	
    	具体子页面的内容...
    	
    {% endblock %}
    

    后台管理页面例子

    一般后台管理页面分为好3-4个部分,header/body/footer,body中又包括左侧菜单栏和右侧内容部分.

    views.py 中的内容:

    def assets(request):
        assets_list=[]
        for i in range(10):
            temp={'hostname':'h1'+str(i),'port':80}
            assets_list.append(temp)
        return render(request,'assets.html',{'assets_list':assets_list})
    
    def userinfo(request):
        user_list=[]
        for i in range(10):
            temp={'username':'h1'+str(i),'salary':80}
            user_list.append(temp)
        return render(request,'userinfo.html',{'user_list':user_list})
    

    母板:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <link rel="stylesheet" href="..." />
        <style>
            .pg-header{
                height: 48px;
                background-color: cadetblue;
            }
            .pg-body{
                min-height: 500px;
            }
            .pg-body .body-menu{
                 20%;
                float: left;
            }
            .pg-body .body-content{
                 80%;
                float: left;
            }
            .pg-footer{
                height: 100px;
                background-color: brown;
            }
            .active{
                background-color: aquamarine;
                color: white;
            }
        </style>
    
        {% block css %}{% endblock %}
    </head>
    <body>
        <div class="pg-header">
            后台系统V1
        </div>
        <div class="pg-body">
            <div class="body-menu">
                <ul>
                    <li><a href="/web/userinfo">用户管理</a></li>
                    <li><a href="/web/assets">资产管理</a></li>
                </ul>
            </div>
            <div class="body-content">
                {% block body %}{% endblock %}
            </div>
    
        </div>
        <div class="pg-footer"></div>
        <script src="xxx"></script>
        {% block js %}{% endblock %}
    </body>
    </html>
    

    子板 assets.html:

    {% extends 'layout.html' %}
    
    {% block body %}
        <table>
            {% for item in assets_list %}
                <tr>
                    <td>{{ item.hostname }}</td>
                    <td>{{ item.port }}</td>
                </tr>
            {% endfor %}
        </table>
    {% endblock %}
    

    子板 userinfo.html:

    {% extends 'layout.html' %}
    
    {% block css %}
        <style></style>
    {% endblock %}
    
    {% block body %}
        <ul>
        {% for item in user_list %}
            <li>{{ item.username }},{{ item.salary }}</li>
        {% endfor %}
        </ul>
    
    {% endblock %}
    
    {% block js %}
        <script>
            document.getElementById('userinfo').className = 'active';
        </script>
    {% endblock %}
    
    

    include小组件

    页面中难免出现重复利用的小图片页面之类的,所以出现了组件这个概念,类似于python中的模块概念,很简单,直接在页面中载入即可.

    比如,需求模板:

    {% extends 'layout.html' %}
    
    {% block body %}
        <table>
            {% for item in assets_list %}
                <tr>
                    <td>{{ item.hostname }}</td>
                    <td>{{ item.port }}</td>
                </tr>
            {% endfor %}
        </table>
    
        {% include 'son.html' %}
        {% include 'son.html' %}
        {% include 'son.html' %}
        {% include 'son.html' %}
        {% include 'son.html' %}
        {% include 'son.html' %}
        <h3></h3>
    
    {% endblock %}
    
    {% block js %}
        <script>
            document.getElementById('assets').className = 'active';
        </script>
    {% endblock %}
    

    组件模板son.html:

    <form>
        <input />
        <input />
        <input />
        <input />
    </form>
    
  • 相关阅读:
    第5节 两牵引轴同步运动
    第4节 动一个牵引轴
    第3节 电控配置简介
    第2节 控制方案的制定
    第1节 中型PLC基本编程思路
    1200与VM(主动)之间的TCP/IP通讯
    西门子1200和温度计的模拟量应用
    西门子1200的高速计数功能和增量编码器功能
    西门子1200和V90之间(位置模式)的PID应用
    面试题68
  • 原文地址:https://www.cnblogs.com/ccorz/p/5843271.html
Copyright © 2011-2022 走看看