zoukankan      html  css  js  c++  java
  • 01:django基础篇

    Django其他篇

    目录:

    1.1 django初探     返回顶部

      1、django、tornado、flask比较

          Django: 1个重武器,包含了web开发中常用的功能、组件的框架;(ORM、Session、Form、Admin、分页、中间件、信号、缓存、ContenType....);

          Tornado: 最大特性就是异步非阻塞、原生支持WebSocket协议;

          Flask:封装功能不及Django完善,性能不及Tornado,但是Flask的第三方开源组件比丰富;

          使用参考

            1. 小型web应用设计的功能点不多使用Flask;
            2. 大型web应用设计的功能点比较多使用的组件也会比较多,使用Django(自带功能多不用去找插件);
            3. 如果追求性能可以考虑Tornado;

      2、MVC和MVT比较

        MVC       Model(数据库 )        View(模板文件)       Controller(业务处理)

            M( Model):  主要封装对数据库层的访问,对数据库中的数据进行增、删、改、查操作。
            V( View):  用于封装结果,生成页面展示的html内容。
            C(Controller):  用于接收请求,处理业务逻辑,与Model和View交互,返回结果。

        MTV       Model(数据库)        Template(模板文件)        View( 业务处理)

            M( Model):  与MVC中的M功能相同,负责和数据库交互,进行数据处理。
            V( View):  与MVC中的C功能相同,接收请求,进行业务处理,返回应答。
            T(Template):  与MVC中的V功能相同,负责封装构造要返回的html。

    1.2 第一个django项目     返回顶部

      1、安装django

           pip3 install django==2.0.4

      2、创建django项目

    C:Users	om>    d:                          # 进入d盘
    D:>    django-admin startproject mysite     # 创建django项目(可以看到c盘生成了mysite文件夹的django项目)
    D:>    cd mysite                            # 进入项目目录
    D:mysite>    python manage.py runserver 127.0.0.1:8000       # 运行mysite项目
    # 浏览器访问:http://127.0.0.1:8000/

      3、创建子应用

          c:mysite>python manage.py startapp app01

      4、django项目和子应用各文件作用

    C:.
    │  db.sqlite3               # sqlite数据库文件(settings.py中默认连接的数据库)
    │  manage.py              # 项目管理脚本
    │
    ├─app01 (子应用目录)
    │  │  admin.py            # 配置django admin后台
    │  │  apps.py
    │  │  models.py            # 配置django表,负责和数据库交互,进行数据处理
    │  │  tests.py
    │  │  views.py             # 接收请求,进行业务处理,返回应答
    │  │  __init__.py
    │  │
    │  └─migrations
    │          __init__.py
    │
    └─mysite
        │  settings.py           # 项目配置文件
        │  urls.py              # 总路由
        │  wsgi.py
        │  __init__.py
    django项目文件注释

      5、settings.py基本配置

          1)配置模板的路径(在项目根路径下创建文件夹  D:mysite emplates

    TEMPLATES = [
        {
           'DIRS': [os.path.join(BASE_DIR,'templates')],
        },
    ]
    TEMPLATE_DIRS = (os.path.join(BASE_DIR,  'templates'),)

          2)配置静态目录(在项目根路径下创建文件夹 D:mysitestatic

    #像ccs和js这些静态文件如果想要使用必须在这里配置路径
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR,'static'),
    )

          3)注释CSRF(如果以post方式提交请求可以先注释这里进行测试)

    MIDDLEWARE = [
        # 'django.middleware.csrf.CsrfViewMiddleware',
    ]

          4) 修改settings.py中时区

    #### 1、Django默认配置是:
    TIME_ZONE = 'UTC'
    LANGUAGE_CODE = 'en-us'
    
    #### 2、Django1.9以前应设置为:
    TIME_ZONE = 'Asia/Shanghai'
    LANGUAGE_CODE = 'zh-cn'
    
    ####3、Django1.9以后至目前的2.1,应设置为:
    LANGUAGE_CODE = 'zh-hans'
    TIME_ZONE = 'Asia/Shanghai'

    1.3 django render/redirect/HttpResponse 和 request.GET request.POST     返回顶部

      1、render/redirect/HttpResponse 函数用法

          render  :  返回html页面

          redirect  :  重定向到新的页面

          HttpResponse  :  返回字符串(一般为json字符串)

    from django.contrib import admin
    from django.urls import path
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('index/', views.index),
    ]
    urls.py
    from django.shortcuts import render,redirect,HttpResponse
    import json
    
    def index(request):
        return render(request, 'index.html', {'users':['zhangsan','lisi','wangwu']})
        # return redirect('https://www.baidu.com')
        # return HttpResponse(json.dumps({"name":"zhangsan"}))
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title</title>
    </head>
    <body>
        <h1>我是首页</h1>
        {{ users }}
    </body>
    </html>
    index.html

      2、模板使用

    from django.contrib import admin
    from django.urls import path
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('index/', views.index),
    ]
    urls.py
    from django.shortcuts import render,redirect,HttpResponse
    
    def index(request):
        return render(request, 'index.html',
                      {
                          'users':['zhangsan','lisi','wangwu'],
                          'data':{"name":"zhangsan","age":100,"sex":"人妖"},
                          'num': 12,
                       })
    views.py
    <body>
        <h1>1、users: 循环列表</h1>
        {% for u in users %}
            <p>{{ u }}</p>
        {% endfor %}
    
        <h1>2、data:循环字典</h1>
        {% for k,v in data.items %}
            <p>{{ k }} -- {{ v }}</p>
        {% endfor %}
    
        <h1>3、if判断</h1>
        {% if num > 16 %}
          <a>num大于16</a>
       {% else %}
          <a>num小于16</a>
       {% endif %}
    </body>
    index.html

    1.4 Django各种url写法     返回顶部

      1、无正则匹配url  (http://127.0.0.1:8000/index/?nid=1&pid=2)

      2、基于(d+)正则的url

      3、基于正则分组(?P<nid>d+),可以不考虑接收参数顺序 (推荐)

      4、使用name构建自己想要的url

      5、Django路由分发    并使用name构建url路径

      re_path(r'app01/',include(('app01.urls','app01'),namespace='app01'))

    from django.contrib import admin
    from django.urls import path, re_path,include
    from app01 import views
    
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        re_path(r'index1/$', views.index1, name='indexname1'),          # 方法1:无正则匹配url
        re_path('index2/(d+)/$', views.index2, name='indexname2'),     # 方法2:基于(d+)正则的url
        re_path('index3/(?P<nid>d+)/(?P<pid>d+)/$', views.index3, name='indexname3'),        # 方法3:基于(d+)正则的url
        re_path('index4/$', views.index4),                               # 方法4:使用name构建自己想要的url
        path('app01/', include('app01.urls', namespace='app01')),       # 方法5:Django路由分发
    ]
    mysite/urls.py
    from django.shortcuts import render,redirect,HttpResponse
    import json
    from django.urls import reverse
    
    
    # 方法1:无正则匹配url( http://127.0.0.1:8000/index1/?uid=1 )
    def index1(request):
        print( request.GET )             # {"uid": "1"}
        nid = request.GET.get('uid')    # 1
        return HttpResponse('无正则匹配url')
    
    
    # 方法2:基于(d+)正则的url(  http://127.0.0.1:8000/index2/1/  )
    def index2(request, uid):
        print( uid )                    # 1
        return HttpResponse('基于(d+)正则的url')
    
    
    # 方法3:基于正则分组(?P<nid>d+)(  http://127.0.0.1:8000/index3/1/2/  )
    def index3(request, nid, pid):
        print(nid)                     # 1
        print(pid)                     # 2
        return HttpResponse('基于正则分组url')
    
    
    # 方法4:使用name构建自己想要的url (http://127.0.0.1:8000/index4/)
    def index4(request):
        url1 = reverse('indexname1')                                    # /index1/
        url2 = reverse('indexname2', args=(1,))                         # /index2/1/2/
        url3 = reverse('indexname3', kwargs={'pid': 1, "nid":2})       # /index3/1/2/
        return render(request, 'index.html')
    
    
    # 方法5:Django路由分发 (http://127.0.0.1:8000/app01/aaa/)
    def aaa(request):
        return HttpResponse('aaa')
    app01/views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title</title>
    </head>
    <body>
        <p><a href="{% url 'indexname1' %}">  无正则匹配: http://127.0.0.1:8000/index/  </a></p>
        <p><a href="{% url 'indexname2' 1  %}"> 基于(d+)正在匹配: http://127.0.0.1:8000/index2/1/  </a></p>
        <p><a href="{% url 'indexname3' 1 2 %}">  基于正则分组url: http://127.0.0.1:8000/index3/1/2/  </a></p>
    </body>
    </html>
    index.html
    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    from django.urls import path,re_path
    app_name='app01'
    from app01 import views
    
    
    urlpatterns = [
        re_path(r'aaa/$', views.aaa, name='aaa'),
    ]
    app01/urls.py

    1.5 Django的CBV和FBV     返回顶部

      1、FBVfunction  base  view:views.py文件中使用函数

    def aaa(request):
        return HttpResponse('aaa')
    FBV写法

      2、CBV(class  base  view):在views.py文件中使用类

          1、 dispatch是父类中用来反射的函数,找对应的函数(比对应函数先执行)

          2、 比如你发送post请求就可以通过dispatch找到对应的post函数进行处理,get就会找到get函数处理

    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    from django.urls import path,re_path
    app_name='app01'
    from app01 import views
    
    
    urlpatterns = [
        re_path(r'home/$', views.Home.as_view(), name='home'),
    ]
    urls.py
    from django.views import View
    class Home(View):
        '''使用CBV时必须要继承view父类'''
        def dispatch(self, request, *args, **kwargs):
            # 调用父类中的dispatch
            result = super(Home,self).dispatch(request, *args, **kwargs)
            # 使用result主动继承view父类,然后return就可以重写父类的dispath方法
            return result
    
        # 在这里使用get发来请求就会调用get方法,使用post发来请求就会调用post方法
        def get(self,request):
            print(request.method)
            return HttpResponse('get')
    
        def post(self,request):
            print(request.method,'POST')
            return HttpResponse('post')
    app01/views.py

    1.6 前后端交互:提交数据     返回顶部

      1、获取请求数据

    # 1、request.POST
    # 2、request.GET
    # 3、request.FILES
    # 4、request.getlist
    # 5、request.method
    # 6、request.path_info                   #获取当前url

      2、举例

    from django.contrib import admin
    from django.urls import path, re_path
    from app01 import views
    
    urlpatterns = [
        re_path(r'login/$', views.login, name='login'),
    ]
    urls.py
    def login(request):
        if request.method == 'GET':
            return render(request, 'login.html')
        elif request.method == 'POST':
            post_data = request.POST                      # {"user": "naiqiang.xiao", "gender": "1", "favor": "33", "city": "bj"}
            mul_list = request.POST.getlist('favor')     # ['11', '22', '33']
            return render(request, 'login.html')
    app01/views.py
        <form action="/login/" method="post" enctype="multipart/form-data">
            <p>
                <span>input提交:</span>
                <input type="text" name="user" placeholder="用户名">
            </p>
    
            {# 1、单选框,返回单条数据的列表 #}
            <p>
                <span>性别: </span>
                男:<input type="radio" name="gender" value="1">
                女:<input type="radio" name="gender" value="2">
            </p>
    
            {# 2、多选框、返回多条数据列表 #}
            <p>
                <span>爱好: </span>
                篮球:<input type="checkbox" name="favor" value="11">
                排球:<input type="checkbox" name="favor" value="22">
                足球:<input type="checkbox" name="favor" value="33">
            </p>
    
            {# 3、多选,返回多条数据的列表 #}
            <p>
                <span>地址: </span>
                <select name="city">
                    <option value="bj">北京</option>
                    <option value="sh">上海</option>
                    <option value="gz">广州</option>
                </select>
            </p>
            <input type="submit" value="提交">
        </form>
    login.html

      3、form表单中三个参数作用

    ''' action="/login/" method="post" enctype="multipart/form-data"  '''
    # 1、action="/login/"      # form表单数据提交的路径
    # 2、method="post"         # 以什么方式提交form表单
    # 3、enctype="multipart/form-data"      # 如果需要提交文件需要这个标注

    1.7 上传图片&预览功能     返回顶部

      1、使用from表单上传图片 及 预览功能

          1) enctype就是encodetype就是编码类型的意思。
          2) 默认情况下,enctype的值是application/x-www-form-urlencoded,不能用于文件上传。
          3) multipart/form-data是指定将文件以二进制的形式上传,这样可以实现多种类型的文件上传。

    from django.contrib import admin
    from django.urls import path,re_path
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        re_path(r'upload/',views.upload),
    ]
    urls.py
    from django.shortcuts import render
    import os
    
    def upload(request):
        if request.method == 'GET':
            return render(request, 'upload.html')
    
        elif request.method == 'POST':
            obj = request.FILES.get('filename')  # 获取上传图片对象
            file_path = os.path.join('static','images', obj.name)  # staticimagesaa.jpg
            f = open(file_path, mode='wb')
            for i in obj.chunks():
                f.write(i)
            f.close()
            imgpath = os.path.join('images',obj.name)  # imagesaa.jpg
            return render(request, 'upload.html',{'imgpath': imgpath})
    app01/views.py
    {% load staticfiles %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title</title>
    </head>
    <body>
        <form action="/upload/" method="post" enctype="multipart/form-data">
            {% csrf_token %}
            <p><input type="file" name="filename"></p>
            <input type="submit" value="提交">
        </form>
            <p>图片预览</p>
            <p><img src="{% static imgpath %}"></p>
    </body>
    </html>
    upload.html

      2、使用jquery ajax上传图片

        1)JQuery AJAX说明

            1、jQuery其实就是一个JavaScript的类库,其将复杂的功能做了上层封装,使得开发者可以在其基础上写更少的代码实现更多的功能

            2、jQuery Ajax本质 XMLHttpRequest 或 ActiveXObject

        2) FormData对象

            1、FormData对象用以将数据编译成键值对,以便用XMLHttpRequest来发送数据。

            2、 其主要用于发送表单数据,但亦可用于发送带键数据(keyed data),而独立于表单使用。

            3、比起普通的ajax,使用FormData的最大优点就是我们可以异步上传一个二进制文件。

        3)contentType:(默认: "application/x-www-form-urlencoded")

            1、发送信息至服务器时内容编码类型(false标识不要对提交的数据)。

            2、如果你明确地传递了一个content-type给 $.ajax() 那么他必定会发送给服务器(即使没有数据要发送)

            3、设置false作用:告诉JQuery不要设置内容格式

        4)processData(默认: true)

            1、默认情况下,通过data选项传递进来的数据,都会处理转化成一个查询字符串

            2、如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。

            3、设置false作用:告诉JQuery不要特殊处理这个数据

    from django.contrib import admin
    from django.urls import path,re_path
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        re_path(r'ajax/$',views.ajax_upload),
    ]
    urls.py
    from django.shortcuts import render,HttpResponse
    import os
    import json
    
    
    def ajax_upload(request):
        if request.method == 'GET':
            return render(request, 'ajaxupload.html')
        elif request.method == 'POST':
            obj = request.FILES.get('fafafa')
            username = request.POST.get('username')  # root
            file_path = os.path.join('static','images', obj.name)  # staticimagesaa.jpg
            with open(file_path,'wb') as f:
                for item in obj.chunks():
                    f.write(item)
            ret = {'code':True,'data':'sucess'}
            return HttpResponse(json.dumps(ret))
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title</title>
    </head>
    <body>
        <div>
            <input type="file" id="fafafa" name="afafaf">
            <a class="upload">上传</a>
        </div>
        <input type="button" value="提交jQuery" onclick="fqSubmit();">
    
        <script src="/static/jquery-1.12.4.js"></script>
        <script>
            function fqSubmit(){
                var file_obj = document.getElementById('fafafa').files[0];
    
                var fd = new FormData();            // FormData对象可以传字符串,也可以传文件对象
                fd.append('username','root');
                fd.append('fafafa',file_obj);
                var xhr = new XMLHttpRequest();
    
                $.ajax({
                    url:'/ajax/',
                    type:'POST',
                    data:fd,
                    //jquery Ajax上传文件必须指定processData,contentType参数
                    processData:false,              //告诉JQuery不要特殊处理这个数据
                    contentType:false,              //告诉JQuery不要设置内容格式
                    success:function(arg){
                        console.log(111,arg);       //后台返回的数据  {"code": true, "data": "sucess"}
                    }
                })
            }
        </script>
    </body>
    </html>
    ajaxupload.html

    1.8 ajax登录 & 一些常用dom 和 jquery操作     返回顶部

      1、ajax登录

    from django.contrib import admin
    from django.urls import path, re_path
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        re_path(r'login/', views.login, name='login'),
    ]
    urls.py
    from django.shortcuts import render,HttpResponse
    import os
    import json
    
    
    def login(request):
        if request.method == 'GET':
            return render(request, 'login.html')
        elif request.method == 'POST':
            print(request.POST)
            username = request.POST.get('username')
            password = request.POST.get('password')
            print(username, password)
            if username == 'tom' and password == '123456':
                return HttpResponse(json.dumps({'status':True}))
            else:
                return HttpResponse(json.dumps({'status':False}))
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title</title>
    </head>
    <body>
        <h2>登录</h2>
        <div style="">
            <p>
                <input name="username" id="username">
            </p>
            <p>
                <input name="password" type="password" id="password">
            </p>
            <p>
                <input type="button" value="提交" onclick="ajaxSubmit()">
            </p>
            <p id="err-msg" style="color: red;"></p>
        </div>
    
        <script src="/static/jquery-1.12.4.js"></script>
        <script>
            function ajaxSubmit() {
                var username = document.getElementById('username').value;
                var password = document.getElementById('password').value;
                $.ajax({
                    url: '/login/',  // 提交url
                    data: {'username':username, 'password':password},  // 提交数据
                    type: 'POST',  // 提交方式
                    dataType: 'JSON',  // 将数据装换成json格式提交
                    traditional: true,  // tradtional为true阻止深度序列化
                    success: function (data) {
                        if(data.status == true){
                            alert('登录成功')
                            document.getElementById('err-msg').innerText = ''
                            location.href='http://www.baidu.com'
                        }else {
                            console.log('在页面显示错误信息')
                            document.getElementById('err-msg').innerText = '用户名或密码错误'
                        }
                    }
                })
            }
        </script>
    </body>
    </html>
    login.html

      2、前后端交互必学知识点

          1.  Dom操作   :   https://www.cnblogs.com/xiaonq/p/7953682.html

          2.  jquery使用整理  :  https://www.cnblogs.com/xiaonq/p/7954562.html

          3.  ajax最全整理  :  https://www.cnblogs.com/xiaonq/p/8013068.html 

      3、make_password & check_password

    from django.contrib.auth.hashers import make_password, check_password
    
    hkey = make_password("123456")  # pbkdf2_sha25615000MAjic...
    ret = check_password("123456","pbkdf2_sha25615000MAjic...")  # True
  • 相关阅读:
    python入门第十七天_生成器 迭代器
    python入门第十六天__列表生成式
    装饰器补充知识点_ @functools.wraps(func)
    函数练习题2
    函数编程练习题1
    迭代器
    生成器的send方法
    函数写生成器
    斐波那契数列
    生成器
  • 原文地址:https://www.cnblogs.com/xiaonq/p/10953264.html
Copyright © 2011-2022 走看看