• Django 之基础续


    1.路由系统之动态路由

    前言:还记得之前的分页效果,这个如何实现呢?答案就是动态路由。

    url(r'^detail/(d+)/$', views.detail),
    url(r'^detail2/(d+)/(d+)/$', views.detail2),
    url(r'^detail3/(?P<p1>d+)/(?P<x2>d+)/', views.detail3),#设定后端对应处理的函数分别为p1,x2

     通过正则表达式,匹配包含数字的URL,交给views中的函数处理,对应的函数要传送匹配的参数,具体如下:

    def detail(request, nid):
        print(nid)
        return HttpResponse('OK')
    # detail2(1,2)
    def detail2(request, xid, nnid):
        print(xid,nnid)
        return HttpResponse('OK')
    
    # detail3(x2=234,p1=123)
    def detail3(request, p1, x2):
        print(p1,x2)
        return HttpResponse('OK')

    那么分页是怎么实现的呢,代码如下:

    ##url
    url(r'^index/(d+)/', views.index),
    ##view
    #生成一个包含字典的列表
    USER_LIST = []
    for item in range(94):
        temp = {"id": item, 'username':'jason'+str(item), 'email': 'email' + str(item)}
        USER_LIST.append(temp)
    def index1(request, page):
        print(page)
        # 1,0-9
        # 2,10-19
        # 3,20-29
        page = int(page)
        start = (page - 1) * 10
        end = page * 10
        user_list = USER_LIST[start:end]#设定每页取值的范围
        # return HttpResponse('OK')
        return render(request, 'index1.html', {'user_list': user_list})
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</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="/cmdb/detail/{{ item.id }}">查看详细</a>
                    </td>
                </tr>
            {% endfor %}
        </table>
    
    </body>
    </html>
    index1.html

    效果如下:

    2.自定义标签方法

    自定义标签目录名必须为templatetags, 否则django无法识别,分两步实现:

    1、创建指定文件,名称不能改 templatetags
    2、创建任意 .py 文件,如:mytag.py
    # 必须不变
    register = template.Library()
    			
    # 创建函数
    @register.filter
    def f1(value):
          value + "666"
    
    3、在html模版的头部执行

    {% load mytag %}
    4、html代码
     k1 = 'VVV'
       {{k1}}    => vvv
       {{k1|f1}} => vvv666 ##将k1通过管道传给f1函数
    5、 settings.py 中注册app

    如下图:

    from django import template
    from django.utils.safestring import mark_safe
    from django.template.base import Node,TemplateSyntaxError
    
    register = template.Library()
    @register.filter
    def f1(value,arg):
        ##filter只能传一个参数,可以使用html中的if语句
        return value + "666" + arg
    
    @register.simple_tag
    def f2(s1,s2,s3,s4):
        #simplet tag 不支持html中的if语句
        return s1 + s2 + s3 + s4
    
    @register.filter
    def f3(value):
        ##filter支持if语句
        if value == 'VVV':
            return True
        return False
    mytag
    def template(request):
        return render(request,
                      'template.html',
                      {'k1':'vvvv','k2':[11,22,33],'k3':{'nid':12,'name':'Jason'}}
    Views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        {% load mytag %}
    </head>
    <body>
        {{ k1 }}
        {{ k1.1 }}
        {{ k1.name }}
        {% for item in k2 %}
            <p>{{ item }},{{ forloop.counter }},{{ forloop.counter0 }},{{ forloop.revcounter }},{{ forloop.first }},{{ forloop.last }}</p>
        {% endfor %}
        {% if k1 == 'vvvv' %}
            <h1>V1</h1>
        {% elif k1 == 'v2' %}
            <h1>V2</h1>
        {% else %}
            <h1>7777</h1>
        {% endif %}
        {% if k1|f3 %}
        <h1>True</h1>
        {% else %}
        <h1>False</h1>
        {% endif %}
        {{ k1 }}
        {{ k1|lower }}
        {{ k1|f1:"jason"}}
        <br>
        {%   f2 1 2 3 4 %}
    </body>
    </html>
    template.html 

     需要注意的tip:

    1.filter

       限制:传参
    支持:模版语言的 if 条件

    2.simple_tag

       不支持:模版语言的 if 条件

     3.模板的继承

    首先了解下模板是什么概念?首先已博客园为例:

    看下面的图片,在点击首页、精华、候选、新闻、管住、我评、我赞的时候  上面、左侧的红色框体都没有变,变得是中间的内容是怎么实现的呢?就是通过母版来实现的

    我们创建一个母版  - 子版去继承母版就可以了,子版里是变化的内容即可。

    详见下面的例子

    1.母版:layout.html

    提别提醒:母版最多允许出现一个母版(可以写多个,但是建议不要写多个)

    <!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 id="userinfo" href="/web/userinfo">用户管理</a></li>
                    <li><a id="assets" 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>
    

     2.子模板

     需要在HTML头部以如下的方式导入母版,有点类似Python导入模块的方式,extends 集成那个模板   ,在加一个block content 来书写变化的内容。

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

     实例如下:

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

     3.导入标签

    如何在html中导入我们想导入的别人的或定制的标签呢,答案是include方法;

    son.html:

    <form>
        <input />
        <input />
        <input />
        <input />
    </form>
    

     include.htm:

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

     效果如下:

    以后比如某些公共的模块可以使用include的方式导入!很方便

    4.Django静态文件配置

    把所有的静态都放在static目录下,比如:css、js、imgs、等

    配置引入static目录,在settings里,否则无法使用static目录下的静态文件,因为他找不到路径!的需要告诉django

    STATIC_URL = '/ff/' #可以自己制定,html引用时要加入此前缀
    STATICFILES_DIRS = (
       os.path.join(BASE_DIR,'statics'),
    )
    

     静态文件目录如下:

    html引用方式如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/ff/style/style.css">
        {#    然后在模板里,我们也会写一个block,如果子版里有需要使用自己的css样式可以自己定义#}
        {% block css %} {% endblock %}
    </head>
    <body>
        <div class="header"><h1>LOGO</h1></div>
        <div class="body">
            <div class="menu">左侧菜单</div>
            <div class="content">
                {#可变的子版内容,这个content和class content无关#}
                {% block content %} {% endblock %}
            </div>
        </div>
        {#    公共的js写到母版中,如果某一个模板里使用自己的js,在写一个block即可#}
        {% block js %} {% endblock %}
    </body>
    </html>

     注:在模板里引入了相应的css和js之后,子版里是默认继承的。如果某个子版想独立使用它自己的js,我们可以通过:{% block css %} {% endblock %}  ||  {% block js %} {% endblock %}来定义!

    登录注册实例

    1.url

    在mysite 这个project下的urls定义路由如下

     url(r'^app01/',include('app01.urls')),
    

     在cmdb这个app中urls定义路由如下:

    from django.conf.urls import url
    from django.contrib import admin
    from cmdb import views
    
    urlpatterns = [
                url(r'^register/', views.register),
                url(r'^login/',views.login),
        ]
    

     views函数定义如下:

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

     html中form表单如何提交的呢?

    <form class="form-horizontal" action="/login/" method="post">

    提交到在form表单中的action里定义:这里的/login/是URL,当咱们访问URL的时候回给执行咱们定义的函数,前面和后面都要有/  并且使用方法为post

    咱们访问的时候是使用的GET方式,当咱们提交的时候使用的是post请求!我们就可以判断!

    def login(request):
        #如果是GET请求
        #如果是POST,检查用户输入
        #print request.method 来查看用户是通过什么方式请求的
        #还有个问题:当你POST的时候,会出现问题,现在临时解决方法是:在seetings里注释掉
        '''
        MIDDLEWARE_CLASSES = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        #'django.middleware.csrf.CsrfViewMiddleware',  注释掉这一行
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        ]
        '''
        if request.method == 'POST':
            input_email = request.POST['email']
            input_pwd = request.POST['pwd']
            if input_email == 'jason' and input_pwd == '123':
                #当登录成功后给它跳转,这里需要一个模块from django.shortcuts import redirect
                #成功后跳转到指定网址
                return redirect('http://www.baidu.com')
            else:
                #如果没有成功,需要在页面告诉用户用户名和密码错误.
                return render(request,'login.html',{'status':'用户名或密码错误'})
                #通过模板语言,来在login.html中添加一个status的替换告诉用户<span>{{ status }}</span>
    
        return render(request,'login.html')
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录</title>
        <!--指定告诉ID用高版本的解析-->
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
        <!-- Bootstrap -->
        <!-- 新 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.4-dist/css/bootstrap.min.css">
    </head>
    <body>
        <div style=" 200px;">
            <form class="form-horizontal" action="/login/" method="post">
              <div class="form-group">
                <label for="inputEmail3" class="col-sm-2 control-label">Email</label>
                <div class="col-sm-10">
                  <input type="email" class="form-control" name="email" placeholder="Email">
                </div>
              </div>
              <div class="form-group">
                <label for="inputPassword3" class="col-sm-2 control-label">Password</label>
                <div class="col-sm-10">
                  <input type="password" class="form-control" name="pwd" placeholder="Password">
                </div>
              </div>
              <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                  <button type="submit" class="btn btn-default">Sign in</button>
                    <span style="color: red;">{{ status }}</span>
                </div>
              </div>
            </form>
    
    
        </div>
    
      <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
      <script src="/static/js/jquery-2.2.1.min.js"></script>
      <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
      <script src="/static/plugins/bootstrap-3.3.4-dist/js/bootstrap.min.js"></script>
    </body>
    </html>
    login.html

    如何利用JQuery封装的ajax实现提交数据到后台呢,方法如下:

    a. 下载Jquery
    b. 放置在static目录下
    c. setting配置
    c. html导入

    $.ajax({
       url: '/index/',
       type: 'POST',
       data: {'username': 'alex','password': '123'},
       success: function(data){
          // 当后台return之后,该函数自动执行
          // data就是后台返回的数据
       }
    })
    

     此例子中ajax非Jquery独有,详细说明详见:http://www.cnblogs.com/wupeiqi/articles/5703697.html

  • 相关阅读:
    C++指针
    写的第一个 JavaCript
    VB.NET中实现"关机/休眠/重启/注销"的类
    VB&VB.NET速查表
    把一个数组的值赋给另一个数组(VB.NET)
    设置装备陈列.htaccess的一些问题结果总结
    httpd.conf文件设置装备布置详解2
    httpd.conf文件设置装备安放详解3
    httpd.conf文件设置详解1
    Red Hat下若何架设FTP做事器
  • 原文地址:https://www.cnblogs.com/jasonwang-2016/p/5838673.html
Copyright © 2020-2023  润新知