• Django的开始


    一 浏览器相关知识

     http:只有依赖一回,属于短链接,不会报错客户端的信息。

     浏览器相当于一个客户端,客户端的链接

     服务端:socket服务端,起服务监听客户端的请求。

    import socket
    sk=socket.socket()
    sk.bind(('192.168.11.38',8888))
    sk.listen(5)
    
    def index():
        with open('轮播网页.html',encoding='utf-8')as f:
            ret=f.read()
            return ret
    def login():
        with open('login.html',encoding='utf-8')as f:
            ret=f.read()
        import pymysql
        conn=pymysql.connect(
            host='127.0.0.1',
            port=3306,
            user='root',
            passwd='0410',
            db='day46'
        )
        cursor=conn.cursor()
        cursor.execute('select * from user')
        user_list=cursor.fetchall()
        cursor.close()
        conn.close()
        res=''
        for i in user_list:
            res += '''
            <tr>
                <td>{}</td>
                <td>{}</td>
                <td>{}</td>
            </tr>
            '''.format(i[0], i[1], i[2])
        tables= ret.replace('@@xx@@',res)
        return tables
    
    
    
    
    def info():
        return "这是个人信息"
    
    info_index=[
        ('/login/',login),
        ('/index/',index),
        ('/info/',info)
    ]
    while True:
        conn,addr=sk.accept()
        print(addr)
        data=conn.recv(8096)
        data3=str(data,encoding='utf-8')
        data1=data3.split('
    
    ')[0]
        print('*'*50)
        print(data1)
        data2=data1.split('
    ')[0].split(' ')[1]
        print(data2)
        ingo_name=None
        for i in info_index:
            if data2==i[0]:
                ingo_name=i[1]
                break
        if ingo_name:
            response=ingo_name()
        else:
            response='404'
    
        conn.send(b'HTTP/1.1 200 0k
    Content-Type:text/html;charset=utf-8
    
    ')
        conn.send(response.encode('utf-8'))
        conn.close()
    View Code

    二 框架的介绍

     tornado:模版都是人家写好的,我们只管拿来使用。

     Django:服务端可以自己写,其他的模版都是别人写好的。

     flask:服务端和模版渲染都是自己写的,函数的功能都是别人写好了的。

     所有的web框架叫做web应用服务器。

    三 django的安装和使用

     安装:pip install django。

     创建项目:django-admin startproject 项目名

     手动创建:

     查看参数:django-admin。

     开启项目:python manage.py runserver

     使用命令创建app:atsrtapp app名

      配置文件的INSTALLED_APPS添加'rbac.apps.RbacConfig',

     响应格式:

      {

      "接收到的想要":回复

    。。。。。

      }

     相关文件夹:

      manage.py:所有django命令,所有的django项目相关的都是基于manage这个文件实现的。

      settings.py:配置文件,客户端可以直接访问这里面的一些文件

      urls.py:函数功能,url内部给函数自动传入了一个参数,就是request参数。

       如果想要获取到url里面的内容,使用正则表达式里面的分组,将要获取的内容括起来,然后会被当作实参传入到函数功能里面去。

    url配置:
    	   注意:url:匹配的是url的路径部分
           import re
           re.findall("^articls/2004/$","articls/2004/asdsa")
    	   
    	无名分组:
           # url(r'^articls/(d{4})/(d{2})$', views.archive3,),  # archive2(request,2000,11)	     
    	
        有名分组:
          # url(r'^articls/(?P<y>d{4})/(?P<m>d{2})$', views.archive4,), # archive2(request,y=2000,m=11) 
    

       blog分发:将一个大的urls文件进行分组,分成多个小的urls文件,然后再在大的urls文件里面调用这些小的urls文件。

    小urls文件
    from django.conf.urls import url, include
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^articls/2004/$', views.archive, ),  # 完全匹配 #  archive(request)
        url(r'^articls/(?P<y>d{4})/(?P<m>d{2})$', views.archive4, ),  # archive2(request,y=2000,m=11)
    ]
    
    
    大urls文件
    from django.conf.urls import url,include
    from django.contrib import admin
    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^index/', views.index),
        url(r'^login.html/', views.login,name="laogou"), # login(request)
        url(r'^foo/', views.foo), # login(request)
    
        ##############路由分发####################
    
        url(r'^app01/', include('app01.urls')) ,  # /app01/articls/2004
    
    
    ]
    View Code

      wsgi.py :socketserver相关,wsgi文件和django结合使用的,django是没有服务端的,而wsgi文件为django提供了一个服务端。

       wsgi文件是一种协议,是web网关接口,分别有两种:wsgiref和uwsgi。

        wsgiref是可以实现基本的,大多数用来调试的。

        uwsgi是用于企业的。

        wsgi导入的文件是:

    from django.core.wsgi import get_wsgi_application
    

      app文件:project  :主要用于业务的分类,是整个项目下的一个程序

       主站,app:专门处理相关的业务,启动app的web命令:

    python manage.py startapp web
    

       后台管理 app:启动app的backend命令:

    python manage.py startapp backend
    

      models文件:主要是写web应用相关的内容。

    四 使用

     views视图分为两大块:一个是请求对象,另一个是响应对象。

      请求对象request:代表所有请求的内容

       request.method:获取请求,请求的方法具体是什么

       request.POST.get('***'):以什么途径发送的请求

       request.GET.get(‘***’):从url中获取具体的什么数据或者内容,在后端函数里面需要使用GET

       request.POST.getlist:同时可以获取多个值,所有的值都是在一个列表里面

       request.encoding:请求的格式

       request.path 和request.info:请求路径的内容,没有数据内容

       request.get_full_path:请求路径的内容,还有数据的内容

    def archive(request):
        print(request.path)  # /app01/articls/2004/
        print(request.path_info)  # /app01/articls/2004/
        print(request.get_full_path())  # /app01/articls/2004/?a=1
    

       request.is_ajax:判断这次的请求是不是ajax请求

       还有request.COOKICS;request.session;request.path等

        GET:
    			
    		URL: 127.0.0.1:8000/class_list/?name=alex&age=18
    		
    		request.GET.get("name")			
    		request.GET.get("age")	
    		
    	
    	POST:
    		
    		<form class="form-horizontal" action="/add_class/" method="post">
    			<div class="form-group">
    				<label for="inputclassname" class="col-sm-2 control-label">班级名称</label>
    				<div class="col-sm-10">
    					<input name="class_name" type="text" class="form-control" id="inputclassname" placeholder="班级名称">
    				</div>
    			</div>
    			<div class="form-group">
    				<div class="col-sm-offset-2 col-sm-10">
    					<button type="submit" class="btn btn-default">提交</button>
    				</div>
    			</div>
    		</form>
    

     request.body:所有的请求数据都会在这里面。

    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    
    
    def login(request):
        if request.is_ajax():
            print(request.body) # b'{"user":"alex","pwd":"123"}'
            # b'user=alex&pwd=123&csrfmiddlewaretoken=PCLE4jNWOmLcmd5LiY1qrwTWQZLpZdSktwwwPswNKg7DhblKO6X1fBDkB05yoNMm'
            print(request.POST) # {'user': ['alex'], 'pwd': ['123'], 'csrfmiddlewaretoken': ['PCLE4jNWOmLcmd5LiY1qrwTWQZLpZdSktwwwPswNKg7DhblKO6X1fBDkB05yoNMm']}
            print(request.GET)  # {}
    
            # user=request.POST.get("user")
            # pwd=request.POST.get("pwd")
            #
            # print(user,pwd)
            # print("=======")
            # import json
            # s=request.body.decode("utf8")
            # d=json.loads(s)
            # print(d.get("user"))
            # print(d.get("pwd"))
            return HttpResponse("OK")
    
    
        return render(request,"index.html")
    
    
    
    def reg(request):
        if request.is_ajax():
            print(request.POST,"=======")
    
            return HttpResponse("OK")
    
        return render(request,"reg.html")
    View Code

     request.FILES:文件上传的地方接收到的是一个文件对象,也就是一个文件句柄,直接.name就是文件名字。

    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    
    
    
    def index(request):
    
        # #print(request.body)
        # print(request.POST) # <QueryDict: {'csrfmiddlewaretoken': ['2Fq1vmv59yRSUxDwlkym3qmk5bNpfdHLGzbTgveW5sdjPvTvRsuXRv6IQc7yENBN'], 'user': ['yuan'], 'cFile': ['day76.txt']}>
        # print(request.FILES)
        #
        # file_obj=request.FILES.get("cFile")
        # name=file_obj.name
        # print(name)  # day76.txt
        # import os
        #
        # from filePut import settings
        # path=os.path.join(settings.BASE_DIR,"app01","static",name)
        # with open(path,"wb") as f_write:
        #     for line in file_obj:
        #         f_write.write(line)
    
    
    
    
    
        return render(request,"index.html")
    
    
    
    def indexAjax(request):
        print(request.body)
        print(request.POST)
        print(request.GET)
    
        # print(request.POST)
        # print(request.FILES)
        # file_obj=request.FILES.get("cFile")
        # name=file_obj.name
        # print(name)  # day76.txt
        # import os
        #
        # from filePut import settings
        # path=os.path.join(settings.BASE_DIR,"app01","static",name)
        # with open(path,"wb") as f_write:
        #     for line in file_obj:
        #         f_write.write(line)
    
        return HttpResponse("123421")
    View Code

     新手三件套:

      导入:from django.shortcuts import

       HttpResponse:http的响应,里面只能够方字符串

       render:渲染,一次请求一次响应。每请求一次就会被渲染。

        render(request, 'html文件')

        render(request,"html文件",{"替换的内容":值})

        render(request,"html文件",locals())   :局部的变量都可以在HTML文件里面使用

       redirect:跳转页面,重定向这一次请求,重定向时,需要多发送一次请求。

    			以登录为例:
    			    第一次请求:
    			        请求url: http://127.0.0.1:8000/login.html/      GET     无请求数据
    					login.html/-------> views.login------>login()
    					响应到一个login.html页面
    					
    				第二次请求:
                         请求url: http://127.0.0.1:8000/login.html/     POST    有请求数据  {"user":"alex","pwd":"123"}
      					 login.html/-------> views.login------>login()
    					 响应的return redirect("/index/")到浏览器,通知浏览器再发送请求:"/index/"
    					 
    					 请求url: http://127.0.0.1:8000/index/       get请求   没有数据
    					 index/ --->url(r'^index/', views.index),---->index()
    					 
    					 响应一个index.html
    
    from django.conf.urls import url
    from django.contrib import admin
    from django.shortcuts import render,redirect
    
    
    
    def mysql():
        import pymysql
        user_dic = {}
        conn=pymysql.connect(host="127.0.0.1", port=3306, user="root", passwd="0410", db="day43", charset="utf8")
        cursor=conn.cursor()
        cursor.execute('select name,password from user')
        user_list = cursor.fetchall()
        cursor.close()
        conn.close()
        for user in user_list:
            user_dic[user[0]]=user[1]
        return user_dic
    
    
    def login(request):
        if request.method=='GET':
            return render(request,'登陆界面.html')
        else:
            user_dic=mysql()
            for user in user_dic:
                if request.POST.get('user')==user and request.POST.get('passwd')==user_dic[user] and request.POST.get('pwd')==user_dic[user]:
                    return redirect('http://www.xiaohuar.com/hua/')
                elif request.POST.get('user')==user and request.POST.get('passwd')==user_dic[user] and request.POST.get('pwd')!=user_dic[user]:
                    return render(request, '登陆界面.html', {'error_msg': '密码输入不一致'})
            else:
                return render(request,'登陆界面.html',{'error_msg':'用户名和密码错误'})
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^login/',login)
    ]
    View Code

     http就是基于一次请求一次响应的。

     模版语言:

      格式1:

       {% for i in **%}

        {{x}}

       {% endfor %}

      格式2:

       {{ 变量名 }}

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            .c1 {
                width: 100%;
                height: 50px;
                background-color:#DDDDDD;
                opacity: 0.3;
            }
    
            .c4{
                width:80%;
                height:50px;
                background-color:#DDDDDD;
                margin-left: 10%;
            }
    
            .c7{
                width: 100px;
                height: 50px;
                float:left;
            }
    
            .c8{
                width: 80px;
                height: 50px;
                float:right;
            }
    
            .c9{
                width: 120px;
                height: 50px;
                float:right;
            }
    
            .c10{
                width: 80px;
                height: 50px;
                float:right;
            }
    
            .c11{
                width: 80px;
                height: 50px;
                float:right;
            }
    
             .c12{
                 width: 50px;
                 height: 50px;
                 float:right;
            }
    
            .s1{
                line-height:50px;
                text-align: center;
                color:#1F1E1E;
            }
    
            .c2{
                width:100%;
                height: 60px;
                background-color: #ffffff;
                margin-top: 20px;
            }
    
            .c5{
                width: 80%;
                height: 60px;
                background-color: #FFFFFF;
                margin-left: 10%;
            }
            .c3{
                width:100%;
                height:auto;
    
            }
    
            .c6{
                width: 80%;
                height: auto;
                margin-left: 10%;
            }
    
            .d1{
                width: 500px;
                height: 400px;
                float: left;
                margin-top: 50px;
            }
    
            .d3{
                width: 500px;
                height: 50px;
                margin-top:60px;
            }
    
            .s2{
                font-weight:600;
                font-size:30px;
                color: #2e2e2e;
                line-height:50px;
                margin-left: 70px;
    
            }
    
            .p1{
                margin-left: 120px;
            }
    
            .p2{
                margin-left: 104px;
            }
    
    
            .i2{
                margin-left: 15px;
            }
    
            .s3{
                color:red;
            }
    
            .p4{
                margin-left: 150px;
            }
    
            .s4{
                color:#0000CC;
            }
    
            .i3{
                font-size: 14px;
            }
    
    
            .p5{
                margin-left: 200px;
            }
    
            .i5{
                font-size: 10px;
                 background-color:red;
            }
    
            .d2{
                width: 314px;
                height:400px;
                float: right;
                margin-top: 50px;
            }
    
            .p6{
                margin-left:30px;
            }
    
    
            .p7{
                margin-top: 50px;
            }
    
        </style>
    </head>
    <body>
    
    <div class="c1">
        <div class="c4">
            <div class="c7"><span class="s1">*收藏网址</span></div>
            <div class="c8"><span class="s1">客户服务</span></div>
            <div class="c9"><span class="s1">VIP会员俱乐部</span></div>
            <div class="c10"><span class="s1">我的订单</span></div>
            <div class="c11"><span class="s1">免费注册</span></div>
            <div class="c12"><span class="s1">登陆</span></div>
        </div>
    </div>
    <div class="c2">
        <div class="c5"><img src="111.png" alt="悟空"></div>
    </div>
    <div class="c3">
        <div class="c6">
            <div class="d1">
                <div class="d3"><span class="s2">注册新用户</span></div>
                <form action="/login/" method="post">
                    <p class="p1"><span class="s3">*</span>用户名:<input type="text" name="user" class="i2"></p>
                    <p class="p1"><span class="s3">*</span>手机号:<input type="text" name="phone" class="i2"></p>
                    <p class="p2"><span class="s3">*</span>登陆密码:<input type="password" name="passwd" class="i2"></p>
                    <p class="p2"><span class="s3">*</span>确认密码:<input type="password" name="pwd" class="i2"></p>
                    <p class="p4"><input type="checkbox" name="ppp"><span class="i3">我已阅读并同意</span><span class="s4 i3">《用户注册协议》</span> </p>
                    <p class="p5"><input type="submit" value="开始登录" class="i5"></p>
                    {{ error_msg }}
                </form>
            </div>
            <div class="d2">
                <p class="p6 p7"><img src="222.png" alt="悟天" width='250px' height="200px"></p>
            </div>
        </div>
    </div>
    </body>
    </html>
    View Code

     empty:for循环为空的时候需要执行的任务

            {% for teacher in  teacher_list %}
    		要做的事儿
    	{% empty %}
    		要做的事儿
    	{% endfor %}        
    

     if判断语句:

      {% if 条件语句 %}

        执行语句

      {% else  %}

        执行语句

      {% endif %}

          {% if student.class_id == class.id %}
               <option selected value="{{ class.id }}">{{ class.cname }}</option>
          {% else %}
               <option value="{{ class.id }}">{{ class.cname }}</option>
          {% endif %}   
    

     识别标签:{{ 变量名|safe}}

    {{ page_html|safe }}
    

     {% csrf_token %}:中间件

     {% url  '别名'  %}:调用别名,在urls文件中,name的值就是别名。

    url(r'^login.html/', views.login,name="Login"), # login(request)
        in template:
            action="{% url 'Login' %}" 		
    	<a href='{% url 'Login' %}'>click</a>
    

      with模板:将深查找赋值一个变量

    {% with total=business.employees.count %}
        {{ total }} employee{{ total|pluralize }}
    {% endwith %}
    

      csrf_token:如果是post的请求需要处理,防跨域。

      在form标签里面使用:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    
    <form action="/login.html/" method="post">
        {% csrf_token %}
        <p>姓名:<input type="text" name="user"></p>
        <p>密码:<input type="password" name="pwd"></p>
        <input type="submit">
    </form>
    
    </body>
    </html>
    View Code

      在ajax里面使用:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
    </head>
    <body>
    
    {% csrf_token %}
    <p>姓名:<input type="text" id="user"></p>
    <p>密码:<input type="password" id="pwd"></p>
    <button>click</button><span class="error"></span>
    <script>
         $("button").on("click",function () {
    
             $.ajax({
                 url:"/foo/",
                 type:"POST",
                 data:{
                     user:$("#user").val(),
                     pwd:$("#pwd").val(),
                     csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val()
                 },
                 success:function (data) {
                     console.log(data);
                     console.log(typeof data);
                     console.log(JSON.parse(data));
                     var data=JSON.parse(data);
                     if (data.user){
                         location.href="/index/"  // 跳转到首页
                     }
                     else {
                         $(".error").html(data.error_msg).css("color","red");
                         setTimeout(function () {
                             $(".error").html("")
                         },2000)
    
                     }
    
                 }
             })
         })
    </script>
    </body>
    </html>
    View Code

     slock.super:在block模板内部使用,添加新的内容,并不会覆盖原来的内容。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    {% block con1 %}
     <p>con11111</p>
    {% endblock %}
    
    {% block con_li%}
        <ul>
        <li>111</li>
        <li>222</li>
        <li>333</li>
        </ul>
    {% endblock %}
    
    </body>
    </html>
    View Code
    {% extends 'app01/base.html' %}
    
    {% block con_li %}
       {{ block.super }}
    
    {% endblock %}
    View Code

      注意:如果在子文件中不使用slock.super模板,就会将父文件中的文本覆盖。

     settings文件的配置:

      添加路径:

    			TEMPLATES = [
    				{
    					'BACKEND': 'django.template.backends.django.DjangoTemplates',
    					'DIRS': [],   # 在这里进行设置
    					'APP_DIRS': True,
    					'OPTIONS': {
    						'context_processors': [
    							'django.template.context_processors.debug',
    							'django.template.context_processors.request',
    							'django.contrib.auth.context_processors.auth',
    							'django.contrib.messages.context_processors.messages',
    						],
    					},
    				},
    			]
    			
    

       注释内容:

    			2. 中间件需要注释一个
    			MIDDLEWARE = [
    			'django.middleware.security.SecurityMiddleware',
    			'django.contrib.sessions.middleware.SessionMiddleware',
    			'django.middleware.common.CommonMiddleware',
    			# 'django.middleware.csrf.CsrfViewMiddleware',
    			'django.contrib.auth.middleware.AuthenticationMiddleware',
    			'django.contrib.messages.middleware.MessageMiddleware',
    			'django.middleware.clickjacking.XFrameOptionsMiddleware',
    		]
    

       静态文件设置:

    			STATIC_URL = '/static/'
    			STATICFILES_DIRS = (
    				os.path.join(BASE_DIR, "ss"),  # 静态文件存放位置
    				
    			)
    
    import os
    
    # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    
    # Quick-start development settings - unsuitable for production
    # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
    
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = '#vofy$6d=w^aoa0kk#8jhtc3mno9o)eil^8-a^u=)cana=9zq^'
    
    # SECURITY WARNING: don't run with debug turned on in production!
    DEBUG = True
    
    ALLOWED_HOSTS = []
    
    
    # Application definition
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
    ]
    
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        # 'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    
    ROOT_URLCONF = 'bigJob.urls'
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')]
            ,
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    
    WSGI_APPLICATION = 'bigJob.wsgi.application'
    
    
    # Database
    # https://docs.djangoproject.com/en/1.11/ref/settings/#databases
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
    
    
    # Password validation
    # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
    
    AUTH_PASSWORD_VALIDATORS = [
        {
            'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
        },
    ]
    
    
    # Internationalization
    # https://docs.djangoproject.com/en/1.11/topics/i18n/
    
    LANGUAGE_CODE = 'en-us'
    
    TIME_ZONE = 'UTC'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = True
    
    
    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/1.11/howto/static-files/
    
    STATIC_URL = '/static/'
    STATICFILES_DIRS=(os.path.join(BASE_DIR,'css'),)
    IEMPLATE_DIRS=(os.path.join(BASE_DIR,'templates'),)
    View Code

     提交数据格式类似于:

    		{
    			“class_name”: ”全栈7期“
    		}
    		
    		request.POST.get("“class_name”:")
    

      select默认选中
      在对应的option上加selected

     检验数据有效性:form组件(django自带),自动判断输入的是否为空

     模态框版form提交:因为模态框里面的提交按钮是放在form表单外面的,需要使用JS代码去建立关联
      $("#modal-submit").on("click", function () {
        $("#myModal form").submit();
      });

     检验状态显示颜色:has-error,如果检验出来就会是红色

    $('#setclassname+span').text(dataobj.status).parent().parent().addClass('has-error')
    
    $(document).ready(function () {
        $('.my-menu-item').on('click', 'a', function () {
                $(this).toggleClass('active');
                var $spanEle = $(this).find('span');
                if ($spanEle.removeClass('glyphicon-menu-left')) {
                    $spanEle.removeClass('glyphicon-menu-left').addClass('glyphicon-menu-down');
                } else {
                    $spanEle.removeClass('glyphicon-menu-down').addClass('glyphicon-menu-left');
                }
            });
            $('#modal-submit').on('click', function () {
                // {#            $('#mymodal from').submit();#}
                var className = $('#inputclassname2').val();
                $.ajax({
                    url: '/modal_add_class/',
                    type: 'post',
                    data: {'classname': className},
                    success: function (data) {
                        if (data === 'OK') {
                            // {#                        if (data.length!=0 ){#}
                            // {#                            var classData=JOSN.parse(data);#}
                            // {#                            var newTr=document.cueateElement('tr');#}
                            // {#                            $(newTr).append('<td>'+classData['id']+'</id>');#}
                            // {#                            $(newTr).append('<td>'+classData['name']+'</id>');#}
                            // {#                            $('td:last').clone().appendTo($(newTr));#}
                            // {#                            $(newTr).appendTo('tbody');#}
                            location.href = '/class_list/';
                        } else {
                            $('#error-msg').text(data).parent().parent().addClass('has-error')
                        }
                    }
                })
            })
    
    
        $('table').on('click','.set_class_list',function () {
            $('#set_mymodal').modal('show');
            var $td=$(this).parent().parent().children();
            var class_id=$($td[0]).text();
            var class_name=$($td[1]).text();
    
            $('#setclassid').val(class_id);
            $('#setclassname').val(class_name)
        });
        $('#set-modal-submit').on('click',function () {
            var classid=$('#setclassid').val();
            var classname=$('#setclassname').val();
            $.ajax({
                url:"/modal_set_class/",
                type:'post',
                data:{'classid':classid, 'classname':classname},
                success:function(data){
                    var dataobj=JSON.parse(data);
                    console.log(dataobj.status);
                    if (dataobj.status==='OK'){
                        location.reload()
                    }else{
                        $('#setclassname+span').text(dataobj.status).parent().parent().addClass('has-error')
                    }
                }
            });
        })
    });
    View Code

    五 AJAX(Async JavaScript and XML)

     url:发送的路由路径

     type:以什么接口的方式

     data:发送的数据

     success:接收数据成功后执行

     error:介绍数据结束后执行

     contentType:标识的事让服务器直到这次请求的格式。

      x-www-form-urlencode:将数据拼接成字符串发送过去,这个是默认的

      json:将数据转成js字符串发送过去,告诉服务器是以一个json格式发送的。

     headers:请求头,需要引用jquery里面的cookie.js文件

     cookie("键"):在ajax中获取cookie的值

     serinlize:将某个表单中的value值一起拼接好了一块发送给服务器端。是一种序列化方法。

     post:ajax封装的一个API,以post接口方式发送,如果是get,就以get方式请求

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script>
        <script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script>
    </head>
    <body>
    
    
    <form id="myForm" action="/reg/" method="post">
        {% csrf_token %}
        <input name="uid" type="hidden" value="1" />
        <input id=user name="username" type="text" value="张三" />
        <input name="password" type="text" value="123456" />
        <select name="grade" id="grade">
            <option value="1">一年级</option>
            <option value="2">二年级</option>
            <option value="3" selected="selected">三年级</option>
            <option value="4">四年级</option>
            <option value="5">五年级</option>
            <option value="6">六年级</option>
        </select>
        <input name="sex" type="radio" checked="checked" value="1" /><input name="sex" type="radio" value="0" /><input name="hobby" type="checkbox" checked="checked" value="1" />游泳
        <input name="hobby" type="checkbox" checked="checked" value="2" />跑步
        <input name="hobby" type="checkbox" value="3" />羽毛球
        <input name="btn" id="btn" type="button" value="点击" />
    
    </form>
    
    
    <script>
        $("#btn").click(function () {
    
            $.ajax({
                url:"/reg/",
                type:"POST",
                //data:$("#myForm").serialize(),
                data:$(":checkbox,:radio,#user,[name='csrfmiddlewaretoken']").serialize(),
                success:function (data) {
                    console.log(data)
                }
    
            })
            
          
        })
    </script>
    <script>
    {#    $(":button").click(function () {#}
    {##}
    {#        $.ajax({#}
    {#            url:"/login/",#}
    {#            type:"POST",#}
    {#            data:JSON.stringify({#}
    {#                user:$("#user").val(),#}
    {#                pwd:$("#pwd").val()#}
    {#                //csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val()#}
    {#            })#}
    {#            ,  // 'user=alex&pwd=123'#}
    {#            //contentType:"application/x-www-form-urlencoded",  // (默认)#}
    {#            //headers:{"X-CSRFToken":$("[name='csrfmiddlewaretoken']").val()},#}
    {#            headers:{"X-CSRFToken":$.cookie("csrftoken")},#}
    {#            contentType:"application/json",#}
    {#            success:function (data) {#}
    {#                 console.log(data)#}
    {#            },#}
    {##}
    {#        })#}
    {#    })#}
    </script>
    </body>
    </html>
    View Code

     ajax可以在不用刷新页面的情况下也可以提交数据。AJAX是jquery封装好了的。

     页面刷新:location.reload()

    location.reload()
    

     页面跳转:location.href='要跳转的页面'

    location.href = '/class_list/';
    

      模态框使用ajax提交,有返回值,在页面可以直接加载数据。

    模态框使用ajax提交,返回值
        在页面直接添加数据
        
        在后端:
        
            - HttpResponse("只能放字符串")
               我有一个Python的字典,要返回给前端:
               要把它转换成字符串:
               json.dumps()
               
        在前端:
            - JSON.parse()      --> 把字符串转换回JS对象
            - JSON.stringify()  --> 把JS对象转换成字符串
        
            
            var className = {"items": [1, 2, 3, 4]}
            $.ajax({
                  url: "/modal_add_class/",
                  type: "post",
                  data: {"classname": className},
                  success: function (data) {
                     console.log(data);
                  }
            }
            
            $.ajax({
                  url: "/modal_add_class/",
                  type: "post",
                  data: json.stringify({"classname": className}),
                  success: function (data) {
                    console.log(data);
                  }
            }
    View Code

     项目目录结构:

            - 目录结构
    		-mysite
    			-mysite
    				-urls.py  配置对应关系 URL-->函数
    				-settings.py 配置文件
    				-wsgi.py  socketserver
    				-views.py 自己写的函数统一放到这里
    				__init__.py
    			-templates  存放模板文件的(html文件)
    				-index.html
    				-class_list.html
    			-static
    				-bootstrap
    					-css
    						-bootstrap.min.css
    					-fonts
    					-js
    				-jQuery.3.2.1.min.js
    			-manage.py   管理你Django项目的(有很多命令)
    						 python manage.py runserver IP:PORT    
    

      cursor.lastrowoid:pymysql下面的一种方法,操作数据库时,返回他们的ID。

        def run_list(self,sql,args=None):
            self.cursor.executemany(sql, args)
            self.conn.commit()
            ret=self.cursor.lastrowid
            return ret
    View Code

     AJAX发送数据:

     data:{“name”: "alex", "habit": ["抽烟", "喝酒“, "烫头"]}  这样不行
     data:{“name”: "alex", "habit": JSON.stringify(["抽烟", "喝酒“, "烫头"])} 这样可以
    

     补充:FormData:组装数据,存放要存放的所有键值对

        form标签下面的enctype:修改请求的格式,

          multipart/form-data:上传文件的二进制数据格式,同时支持表单的数据上传。

        ProcessData:让数据是否编码成相对应的编码格式,如果为true,使用contentType进行编码格式,如果为false,就不进行contentType编码处理。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script>
        <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script>
    </head>
    <body>
    
    <form action="/index/" method="post" enctype="multipart/form-data">
         {% csrf_token %}
        <p>姓名: <input type="text" name="user"></p>
        <p>文件: <input type="file" name="cFile"></p>
        <input type="submit">
    </form>
    
    
    <hr>
    
        {% csrf_token %}
        <p>姓名: <input type="text" id="user"></p>
        <p>文件: <input type="file" id="cFile"></p>
        <input type="button" value="submit">
    
    
    <script>
        $(":button").click(function () {
            var $formData=new FormData() ;
            $formData.append("user",$("#user").val());
            $formData.append("cFile",$("#cFile")[0].files[0]);
    
    
    
            $.ajax({
                url:"/indexAjax/",
                type:"post",
                data:{
                    cf:$("#cFile")[0].files[0]
                },
                contentType:false,
                processData:false,    // 不对数据做预处理,不进行任何编发
                headers:{"X-CSRFToken":$('[name="csrfmiddlewaretoken"]').val()},
                success:function (data) {
                    console.log(data)
                }
            })
    
        })
    </script>
    </body>
    </html>
    View Code

     django的一些特殊操作:

      母板的继承:{% extends 'base.html' %}

    在母板里面定义block
        - 页面布局的block
        - pasge-css
        - page-js
    

       引用小组件:{% include 'nav.html' %}

     django详细信息:http://www.cnblogs.com/liwenzhou/p/7931828.html

    六登陆验证

     cookic定义:保存在浏览器的键值对;服务端可以在浏览器上面写cookic,响应头里面会有set-cookic;浏览器每次发送请求都会携带cookic。下次访问时判断cookie状态

     cookic的应用:使用在用户登陆和保存用户登陆的。

     跳转回登陆之前的哪个页面:在url上面加上一个跳转url的装饰器。

     request的其他方法:

      request.get_full_path:获取请求的url

      request.COOKIC.get:获取具体的cookic值

      request.set_cookic:设置cookic的值

      request.delete_cookic:删除cookic值

     sookic的一些参数:

      key:键是什么

      value:值是多少

      max_age:保存时间,以秒为单位

      expires:保存到一个具体的时间

      domain:域名

      secure=False:加密用的Https

      httponly-False:js的代码不能够读取cookic,只能够浏览器发请求时携带cookic 

    response.set_signed_cookie("login2", "1", max_age=10, salt="PythonFullstackS7")
    

     设置加盐的cookic:set_signed_cookic,下面的salt后面加上自己要加的哪个盐

    response.set_signed_cookie("login2", "1", max_age=10, salt="PythonFullstackS7")
    

     获取加盐的cookic:get_signed_cookic,下面的salt后吗加上自己要获取的那个cookic盐值。

    request.get_signed_cookie("login2", salt="PythonFullstackS7", default=None)
    

     七 js补充

     JSON.stringify:将js对象转成字符串类型

     JSON.parse:将字符串类型转成js对象

    data:{'teacher_name':teacherName,'teacher_class_id':JSON.stringify(teacherClassID)},
    var dataobj=JSON.parse(data);
    

    八 分页

     建议:每个页面最多显示11个页码

     而django内置的分页只有上一页和下一页:

     1 from django.shortcuts import render
     2 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
     3 
     4 L = []
     5 for i in range(999):
     6     L.append(i)
     7 
     8 def index(request):
     9     current_page = request.GET.get('p')
    10 
    11     paginator = Paginator(L, 10)
    12     # per_page: 每页显示条目数量
    13     # count:    数据总个数
    14     # num_pages:总页数
    15     # page_range:总页数的索引范围,如: (1,10),(1,200)
    16     # page:     page对象
    17     try:
    18         posts = paginator.page(current_page)
    19         # has_next              是否有下一页
    20         # next_page_number      下一页页码
    21         # has_previous          是否有上一页
    22         # previous_page_number  上一页页码
    23         # object_list           分页之后的数据列表
    24         # number                当前页
    25         # paginator             paginator对象
    26     except PageNotAnInteger:
    27         posts = paginator.page(1)
    28     except EmptyPage:
    29         posts = paginator.page(paginator.num_pages)
    30     return render(request, 'index.html', {'posts': posts})
    View Code

     分页的准备:

      1. 封装:将一些重用的方法封装到一个类里面去,随时都可以调用

      2.app程序准备

    """
    分页组件使用示例:
    
        obj = Pagination(request.GET.get('page',1),len(USER_LIST),request.path_info)
        page_user_list = USER_LIST[obj.start:obj.end]
        page_html = obj.page_html()
    
        return render(request,'index.html',{'users':page_user_list,'page_html':page_html})
    
    
    """
    
    
    class Pagination(object):
        def __init__(self,current_page,all_count,base_url,per_page_num=10,pager_count=11):
            """
            封装分页相关数据
            :param current_page: 当前页
            :param all_count:    数据库中的数据总条数
            :param per_page_num: 每页显示的数据条数
            :param base_url: 分页中显示的URL前缀
            :param pager_count:  最多显示的页码个数
            """
    
            try:
                current_page = int(current_page)
            except Exception as e:
                current_page = 1
            if current_page <1:
                current_page = 1
    
            self.current_page = current_page
    
            self.all_count = all_count
            self.per_page_num = per_page_num
    
            self.base_url = base_url
    
            # 总页码
            all_pager, tmp = divmod(all_count, per_page_num)
            if tmp:
                all_pager += 1
            self.all_pager = all_pager
    
    
            self.pager_count = pager_count
            self.pager_count_half = int((pager_count - 1) / 2)
    
        @property
        def start(self):
            return (self.current_page - 1) * self.per_page_num
    
        @property
        def end(self):
            return self.current_page * self.per_page_num
    
        def page_html(self):
            # 如果总页码 < 11个:
            if self.all_pager <= self.pager_count:
                pager_start = 1
                pager_end = self.all_pager + 1
            # 总页码  > 11
            else:
                # 当前页如果<=页面上最多显示11/2个页码
                if self.current_page <= self.pager_count_half:
                    pager_start = 1
                    pager_end = self.pager_count + 1
    
                # 当前页大于5
                else:
                    # 页码翻到最后
                    if (self.current_page + self.pager_count_half) > self.all_pager:
                        pager_end = self.all_pager + 1
                        pager_start = self.all_pager - self.pager_count + 1
                    else:
                        pager_start = self.current_page - self.pager_count_half
                        pager_end = self.current_page + self.pager_count_half + 1
    
            page_html_list = []
    
            first_page = '<li><a href="%s?page=%s">首页</a></li>' % (self.base_url,1,)
            page_html_list.append(first_page)
    
            if self.current_page <= 1:
                prev_page = '<li><a href="#">上一页</a></li>'
            else:
                prev_page = '<li><a href="%s?page=%s">上一页</a></li>' % (self.base_url,self.current_page - 1,)
    
            page_html_list.append(prev_page)
    
            for i in range(pager_start, pager_end):
                if i == self.current_page:
                    temp = '<li class="active"><a href="%s?page=%s">%s</a></li>' % (self.base_url,i, i,)
                else:
                    temp = '<li><a href="%s?page=%s">%s</a></li>' % (self.base_url,i, i,)
                page_html_list.append(temp)
    
            if self.current_page >= self.all_pager:
                next_page = '<li><a href="#">下一页</a></li>'
            else:
                next_page = '<li><a href="%s?page=%s">下一页</a></li>' % (self.base_url,self.current_page + 1,)
            page_html_list.append(next_page)
    
            last_page = '<li><a href="%s?page=%s">尾页</a></li>' % (self.base_url,self.all_pager,)
            page_html_list.append(last_page)
    
            return ''.join(page_html_list)
    View Code

      3 实现分页:数据切片获取;显示出实现的页码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.min.css">
    </head>
    <body>
    <div class="container">
        <h1>欢迎登陆:{{ user }}   <a href="/logout/">注销</a></h1>
    
    
        <table class="table table-bordered">
            <thead>
            <tr>
                <th>ID</th>
                <th>姓名</th>
                <th>操作</th>
            </tr>
            </thead>
            <tbody>
            {% for item in users %}
                <tr>
                    <td>{{ item.id }}</td>
                    <td>{{ item.name }}</td>
                    <td><a href="/edit/{{ item.id }}/?">编辑</a></td>
                </tr>
            {% endfor %}
            </tbody>
        </table>
    
        <div style="text-align: center">
            <ul class="pagination">
                {{ page_html|safe }}
    
            </ul>
        </div>
    </div>
    </body>
    </html>
    View Code

    九 session的介绍

     session的原理:输入用户名后回随机返回给浏览器一个字符串,然后服务端自己页保留一样的字符串,当浏览器在次访问时,服务端回拿着浏览器发过来的字符串和自己保存的字符串进行比较,如果不一致会提示;如果一致,找到相对应的信息,根据用户需求是否返回相对应的内容。

     session就相当于保存在服务端的键值对,而cookic就相当于保存在浏览器上面的键值对。而session是依赖于cookic的。

     操作: 

      设置值:直接调用session

    request.session['username']='用户名'
    

       内部操作:

    1 设置set_cookie,返回一组字符串给浏览器。
    
    2 自己报保存一样的字符串,作为键值对的键,然后将相关信息作为值保存为键值对的值。
            sessionkey                  sessiondate
            字符串                          上传保存的记录
    View Code

      取值:获取浏览器的用户字符串

    request.session.get()
    

       内部操作:

    '''
             uuid=request.COOKIE.get("sessionID") # 2134shdc329cbk398asdbk2
             django的session表中做过滤:  
             session_user=session.objects.filter(session-key="2134shdc329cbk398asdbk2").first()
             ret=session_user.session_data.get("Is_login") #  {"Is_login":True,"user":"alex"}   
            
        '''
    View Code

      删除:删除具体某一个值

    del request.session['想要删除的哪个key']
    

         删除整条记录:获取浏览器的随机字符串,在根据字符串去服务端比较并删除对应的记录。

    request.session.delect()
    

      创建和保存session的命令:主要是对数据库的迁移

    python manage.py makemigrations
    python manage.py migrate
    

      创建好的session可以存放着任何位置,默认存放在数据库:

    # ###################### session 配置信息 ##########################
    SESSION_ENGINE = 'django.contrib.sessions.backends.db'  # 引擎(默认)
    # SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎  存放在缓存里面
    # SESSION_CACHE_ALIAS = 'default' # 表示那台机器?
    
    # SESSION_ENGINE = 'django.contrib.sessions.backends.file'  # 引擎   存放在文件里面
    # SESSION_FILE_PATH = None  # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()                                            # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T
    
    # SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎  数据库加缓存
    
    # SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎  加密cookic和Session
    
    SESSION_COOKIE_NAME = "sessionid"  # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
    SESSION_COOKIE_PATH = "/"  # Session的cookie保存的路径(默认)
    SESSION_COOKIE_DOMAIN = None  # Session的cookie保存的域名(默认)
    SESSION_COOKIE_SECURE = False  # 是否Https传输cookie(默认)
    SESSION_COOKIE_HTTPONLY = True  # 是否Session的cookie只支持http传输(默认)
    SESSION_COOKIE_AGE = 1209600  # Session的cookie失效日期(2周)(默认)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False  # 是否关闭浏览器使得Session过期(默认)
    
    # SESSION_SAVE_EVERY_REQUEST = False  # 是否每次请求都保存Session,默认修改之后才保存(默认)
    SESSION_SAVE_EVERY_REQUEST = True  # 是否每次请求都保存Session,默认修改之后才保存(默认)    
    View Code

      使用了session以后,用户于用户之间是不会混淆的。

     db.sqlite文件:直接链接到数据库的,将用户的记录可以直接保存

     session和cookic的区别是:

      session执行的速度慢一些,但是安全性高

      cookic执行的速度快一些,但是安全性低

     Template:模板对象,实例化处理的就是一个模板对象

      将页面的设计和Python的代码分离开会更干净简洁更容易维护。 我们可以使用 Django的 模板系统 (Template System)来实现这种模式

    def current_time(req):
        # ================================原始的视图函数
        # import datetime
        # now=datetime.datetime.now()
        # html="<html><body>现在时刻:<h1>%s.</h1></body></html>" %now
    
    
        # ================================django模板修改的视图函数
        # from django.template import Template,Context
        # now=datetime.datetime.now()
        # t=Template('<html><body>现在时刻是:<h1>{{current_date}}</h1></body></html>')
        # #t=get_template('current_datetime.html')
        # c=Context({'current_date':str(now)})
        # html=t.render(c)
        #
        # return HttpResponse(html)
    
    
        #另一种写法(推荐)
        import datetime
        now=datetime.datetime.now()
        return render(req, 'current_datetime.html', {'current_date':str(now)[:19]})
    View Code

     在调用这些 属性时用大的就是点,如果点方法,内能点没有参数的方法

    def index(request):
    
        import time
        c=time.time()
        '''
          render方法的过渡应用:
          t=Template("<html><body>现在时刻是:<h1>{{current_date}}</h1></body></html>")
          c=Context({"current_date":c})
          html=t.render(c)
          return HttpResponse(html)
        '''
    
        l=[111,222,333]
        d = {"name": "alex"}
        class Person():
            def __init__(self,name,age):
                self.name=name
                self.age=age
            def dream(self):
                return ("dream.....")
    
        alex=Person(name="alex",age=34)
        egon=Person(name="egon",age=9000)
        nacha=Person(name="nacha",age=3)
    
        person_list=[alex,egon,nacha]
    
        return render(request,"app01/index.html",{"l":l,"d":d,"person_list":person_list})
    View Code
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <h1>Current time {{ c }}</h1>
    
    <hr>
    <p>{{ l.2 }}</p>
    <p>{{ d.name}}</p>
    <p>{{ person_list.1.name }}</p>
    <p>{{ person_list.1.age }}</p>
    
    <hr>
    {% for person in person_list %}
           <p>{{ person.name }},{{ person.age }}</p>
    {% endfor %}
    <hr>
    {{ person_list.1.dream }}
    </body>
    </html>
    View Code

     Context:上下文对象,实例化出来的是一个上下文对象

    十 模板过滤器

     练习:datetime.datetime.now():当前时,返回的是一个时间对象,每一个时间对象都可以点方法取出对应的值

    def index(request):
    
        import time
        c=time.time()
        '''
          render方法的过渡应用:
          t=Template("<html><body>现在时刻是:<h1>{{current_date}}</h1></body></html>")
          c=Context({"current_date":c})
          html=t.render(c)
          return HttpResponse(html)
        '''
        i=10
        l=[111,222,333]
        d = {"name": "alex"}
        class Person():
            def __init__(self,name,age):
                self.name=name
                self.age=age
            def dream(self):
                return ("dream.....")
    
        alex=Person(name="alex",age=34)
        egon=Person(name="egon",age=9000)
        nacha=Person(name="nacha",age=3)
        person_list=[alex,egon,nacha]
    
        import datetime
    
        t=datetime.datetime.now()
        l2=[]
        fileSize=12341234
        s="hello world"
        content="hello world hello world hello world hello world"
        a="<a href=''>click</a>"
        #return render(request,"app01/index.html",{"l":l,"d":d,"person_list":person_list})
        return render(request,"app01/index.html",locals())
    
    def login(request):
        if request.method=="POST":
            user=request.POST.get("user")
            pwd=request.POST.get("pwd")
    
            if user=="alex" and pwd=="123":
                return redirect("/index/")
    
        return render(request,"app01/login.html")
    
    def archive(request):
        print(request.path)  # /app01/articls/2004/
        print(request.path_info)  # /app01/articls/2004/
        print(request.get_full_path())  # /app01/articls/2004/?a=1
        # select * from Article where year=2004
    
        return HttpResponse("2004")
    
    def archive2(request,year):
    
        return HttpResponse(year)
    View Code

      add:假发过滤器,将变量的数值加上后面的数字

    <p>{{ i|add:5 }}</p>
    

      date:日期过滤器

    <p>{{ t|date:"Y-m-d H:i" }}</p>
    

      length:长度过滤器

     default:提示用户信息

    <p>{{ l2|default:"没有符合要求的内容" }}</p>
    

      filesizeformat:文件大小过滤器

    <p> 文件大小:{{ fileSize|filesizeformat }}</p>
    

      slice:切片过滤器

    <p>{{ s|slice:"2:" }}</p>
    

      truncatechars:按照字符截断

     truncatwords:按照单词截断

    <p>{{ content|truncatechars:9 }}</p>
    <p>{{ content|truncatewords:3 }}</p>
    

       

       

  • 相关阅读:
    购买软件,主要购买服务;没有服务软件,不要钱,也不要用
    ArcGIS二次开发实践— — 遍历ToolBox中的工具!
    arcgis 3种方法快速制作tpk文件(转)
    ArcGIS10.x Engine直连提示连接超时ORA-12170 来自:http://www.iarcgis.com/?p=1004
    地球Gauss_Kruger中央0度经线图
    zoom to raster resolution
    2015年十亿美元级“独角兽公司”都是怎样的? 美国69家成榜首
    这103家独角兽公司,有谁能在美国过上好日子?
    全球各地最全102家“独角兽”企业名单
    2016年中国独角兽企业估值榜 TOP300
  • 原文地址:https://www.cnblogs.com/fangjie0410/p/7896589.html
Copyright © 2020-2023  润新知