• Django框架的前奏(安装及介绍)


    几个重要的概念:

    web的本质:

    浏览器中输入网址敲回车发生了几件事?

      1.浏览器向服务端发送请求

      2.服务端接收请求

      3.服务端返回相应的响应

      4.浏览器接收响应  根据特定的规则渲染页面展示给用户看

    HTTP协议:

      超文本传输协议,规定了浏览器与服务端之间消息传输的数据格式

    四大特性:

      1.基于请求响应

      2.基于TCP/IP之上的作用于应用层的协议

      3.无状态(服务端无法保存用户的状态,多次请求,任然不记住,还如初见)

      4.无连接(请求来一次就响应一次,之后就立马断开连接,两者之间就不再有任何关系了)

    websocket 相当于是HTTP协议的一个大的补丁 它支持长连接

    请求数据格式:

      请求首行(标识HTTP协议版本,当前请求方式)

      请求头(一大堆k,v键值对)

      请求体(携带的是一些敏感信息比如 密码,身份证号等)

     响应数据格式:

    1.响应首行(标识HTTP协议版本,响应状态码)
     2.响应头(一大堆k,v键值对)
      3.响应体(返回给浏览器页面的数据 通常响应体都是html页面)

    响应状态码:

      用一串简单的数字来表示一些复杂的转态或者提示信息

    具体表现形式:

      1xx:服务端已经成功接收到了你的数据正在处理,你可以继续提交额外的数据

      2xx:服务端成功响应,你想要的数据(请求成功 200)

      3xx:重定向(当你在访问一个需要登录之后才能访问的页面 你会发现窗口会自动调到登录页面  301 302)

      4xx:请求错误(请求资源不存在404,请求不合法不符合内部规定会权限不够403)

      5xx:服务器内部错误(500) 系统崩掉:洪水攻击 系统瘫痪等

    HTTP状态码

    200 返回正常

    304 服务端资源无变化,可使用缓存资源

    400 请求参数不合法

    401 未认证

    403 服务端禁止访问该资源

    404 服务端未找到该资源

    500 服务端异常

    请求方式:

    1.get请求

      朝服务端要资源(比如浏览器窗口输入www.baidu.com)

    2.post请求

      朝服务端提交数据(比如用户登录 提交用户名和密码)

    GET 向服务器获取指定资源;

    POST 向服务器提交数据,数据放在请求体里

    两者最直接的区别,GET请求的参数是放在URL里的,POST请求参数是放在请求body里的;

    HTTP GET请求的格式:

    HTTP响应的格式:

    Django推导过程

    手写简易版的web框架:

      实现在服务端输入请求头后有相应的响应内容(动态)

    import socket
    
    server = socket.socket() #括号内不写默认是tcp协议
    server.bind(("127.0.0.1",8080))
    server.listen(5)
    
    while True:
        conn,addr = server.accept()
        data = conn.recv(1024)
        conn.send(b"HTTP/1.1 200 OK
    
     hello world")  # 必须遵循HTTP协议
        print(data)
        data = data.decode("utf-8")
        # "b'GET /login HTTP/1.1
    Host:切割获取客户端页面返回的类型login"
        current_path = data.split("
    ")[0].splist(' ')[1]
        print(current_path)
        if current_path =="/index":
            with open(r":python脱产10期视频day511 纯手撸html文件.html",'rb') as f:
                conn.send(f.read())
        elif current_path =='/login':
            conn.send(b'login')
        else:
            conn.send(b"hello world!")
        conn.close()
        

     通过post请求,指定输入后缀就能访问固定存在的资源

    类型的转换技巧:

    data = b'hello world'
    data = str(data,encoding='utf-8')
    print(data)
    data = bytes(data,encoding='utf-8')
    print(data)
    
    "当不知道用encodeing 还是 incodeing时 考虑加上类型转"

    WSGI(Web Server Gateway Interface)就是一种规范,它定义了使用Python编写的web应用程序与web服务器程序之间的接口格式,实现web应用程序与web服务器程序间的解耦。

    常用的WSGI服务器有uwsgi、Gunicorn。而Python标准库提供的独立WSGI服务器叫wsgiref,Django开发环境用的就是这个模块来做服务器

    基于wsgiref写的web框架

      我们利用wsgiref模块来替换我们自己写的web框架的socket server部分:

    """
    根据URL中不同的路径返回不同的内容--函数进阶版
    返回HTML页面
    让网页动态起来
    wsgiref模块版
    """

       基于wsgiref模块及拆分成不同的文件之后,
    加一个功能只需要在两个地方修改代码即可
      1.urls.py  路由与视图函数的对应关系
      2.views.py  视图函数

         

     基于wsgiref模块写的web代码演示如下:

    from wsgiref.simple_server import make_server
    from urls import urls
    from views import *
    
    def run(env,response):
        """
        env是请求相关的数据
        response是响应相关的数据
        """
        # print(env)
        response('200 OK',[])
        current_path = env.get('PATH_INFO')
        # print(current_path)
        # if current_path == '/index':
        #     return [b'index']
        # elif current_path == '/login':
        #     return [b'login']
        # 定义一个存储函数名的标志位
        func = None
        for url in urls:
            # 判断当前url在不在元组内
            if url[0] == current_path:
                # 只要匹配上了  就把url后缀对应的函数名赋值给func
                func = url[1]
                # 一旦匹配上 应该立刻退出for循环 节省资源
                break
        # 对变量func做判断
        if func:
            res = func(env)
        else:
            res = errors(env)
        return [res.encode('utf-8')]
    
    if __name__ == '__main__':
        server = make_server('127.0.0.1',8080,run)
        # 实时监测127.0.0.1:8080地址 一旦有客户端来连接 会自动加括号调用run方法
        server.serve_forever()  # 启动服务端
        
    # 对象加括号调用  触发--call--

    拆分代码,封装方法,形成动态网页

    urls

    from views import *
    
    urls = [
        ('/index',index),
        ('/login',login),
        ('/reg',reg),
        ('/get_time',get_time),
        ('/get_user',get_user),
        ('/get_db',get_db),
    ]

    views:

    利用jinja2渲染htlm页面

    def index(env):
        return 'index'
    def login(env):
        return 'login'
    def errors(env):
        return '404 error'
    def reg(env):
        return 'reg'
    
    from datetime import datetime
    def get_time(env):
        # 借助于时间模块 现在后端获取到时间数据
        current_time = datetime.now().strftime('%Y-%m-%d %X')
        with open(r'templates/02 get_time.html','r',encoding='utf-8') as f:
            data = f.read()  # data其实就是一串字符串  仅此而已!!!
        data = data.replace('$$time$$',current_time)
        return data
    
    页面的渲染
    from jinja2 import Template def get_user(env): user_dict = {'username':'jason','password':'123','hobby':['read','game','running']} with open(r'templates/03 get_user.html','r',encoding='utf-8') as f: data = f.read() temp = Template(data) res = temp.render(data = user_dict) # 将user_dict传递给前端页面 前端页面通过变量名data就能够获取到该字典 return res

    动态展示数据到html
    import pymysql def get_db(env): conn = pymysql.connect( host = '127.0.0.1', port = 3306, user = 'root', password = '123', database = 'day51', charset = 'utf8', autocommit = True ) cursor = conn.cursor(pymysql.cursors.DictCursor) sql = "select * from userinfo" affect_rows = cursor.execute(sql) data = cursor.fetchall() # print(data) with open(r'templates/04 get_db.html','r',encoding='utf-8') as f: data1 = f.read() temp = Template(data1) res = temp.render(user_list= data) return res

    动静态网页,实时获取数据

    静态网页:数据是写死的,万年不变,不能更改

    动态网页:数据不是写死的,是动态获取到的

    1.后端实时获取当前时间"传递"给前端页面展示
    2.后端从数据库获取数据"传递"给前端页面展示

    在Django中把HTLM文件统一存放在:templates 文件夹中  也叫模板文件

    jinja2模块

    安装:pip3 install jinja2

    由于flask框架是依赖于jinja2的 所以下载flask框架也会自带jinja2模块

    jinja2的作用:模板的渲染 包含了 模板语法

    模板语法:(贴近python语法)

      前端也能够使用后端的一些语法,操作后端传入的数据

    {{ }}:变量相关

        <p>{{data}}</p>
        <p>{{data['username']}}</p>
        <p>{{data.password}}</p>
        <p>{{data.get('hobby')}}</p>    

    模板的for语法:输入for+TAB键 即可补全

     {% %}逻辑相关

        {%for user_dict in user_list%}
            <tr>
                <td>{{user_dict.id}}</td>
                <td>{{user_dict.name}}</td>
                <td>{{user_dict.password}}</td>
            </tr>
        {%endfor%}
        

    捋推到思路的过程:

    1.手写web框架

      1.1.手动书写socket代码

      1.2.手动处理http数据

    2.基于wsgiref 模块帮助我们处理socket以及HTTP数据

    wsgiref模块

      1.请求来的时候 解析http数据 帮你打包成一个字典传输给你 便于你操作各项数据
      2.响应走的时候 自动帮你把数据再打包成符合http协议格式的样子 再返回给前端

    3.封装路由与视图函数对应关系  以及视图函数文件   网站用到的所有的html文件全部放在了templates文件夹下

    1.urls.py 路由与视图函数对应关系
    2.views.py  视图函数(视图函数不单单指函数 也可以是类)
    3.templates  模板文件夹
    

    4.基于jinja2实现模板的渲染

    模板的渲染
      后端生成好数据 通过某种方式传递给前端页面使用(前端页面可以基于模板语法更加快捷简便使用后端传过来的数据)

    web框架

    python三大主流web框架:Django、Flask、Tornado

    1.Django:大而全 自带的功能特别特别多;就类似于航空母舰  有时候过于笨重
    2.Flask:短小精悍  自带的功能特别特别少;全都是依赖于第三方组件
    	flask框架第三方的组件特别多;如果把flask第三方全部加起来;完全可以盖过Django
    	比较受限于第三方的开发者
    3.Tornado:天生的异步非阻塞框架;速度特别快 能够抗住高并发
    	可以开发游戏服务器
    

    三者的区别:

    A:socket  B:路由与视图函数匹配  C:模板语法

                    Django
    			A:用的别人的 wsgiref
    			B:自己写的
    			C:自己写的  
    		Flask
    			A:用的别人的 wsgiref>>> werkzeug
    			B:自己写的
    			C:用的别人的 jinja2
    		Tornado
    			A,B,C全都是自己写的                
    

    Django

    注意事项(容易造成bug)

    1.你的计算机的名称不能有中文
    2.文件的命名尽量也不要用中文
    3.一个pycharm窗口只能有一个项目 不要把多个项目放在一个窗口下
    

     如果出现的“encoding”,优先考虑是文件名问题

    Django版本问题 

    目前有的版本:1.x  2.x

     面试小技巧:问你们公司Django用的是什么版本的?

      答:之前用的是1.xx  慢慢过渡到可维护的2.2xx(透露年限问题)

    学习过程中以diango1.11版本为主

    django下载

      命令行安装:pip3 install diango ==1.11.12

    如何确认是否安装成功

      命令行敲 django-admin

    如何创建django项目

    命令行式
    	1.命令行创建django项目
    	  django-admin startproject 项目名
    	2.命令行创建django应用(一个应用对应一块儿独立的功能)
    	  django-admin startapp 应用名
    	  python manage.py startapp 应用名
    	3.命令行启动django项目
    	  python manage.py runserver 
    	  (******)
    	  注意 用命令行创建django项目  不会自动新建templates模板文件夹
    	  需要你自己手动创建 并且需要你自己去settings.py文件中注册该文件路径
    	pycharm快捷方式
    

    命令行创建diango项目:                             创建后的文件夹中包含:       

     

    创建应用名app

    app概念
      django项目就类似于是一所大学,app就是大学里面不同的学院
      每个学院都有自己独立的功能

    老男孩在创建应用名时,习惯写成app xxx  如app01 ...

     

     app创建后的自带的py文件

     命令行启动Django项目

    Bug亲测:千万别安装python3.7版本的否则启动不了Django项目,报错未安装匹配到Django

    链接后提示:

     pycharm快捷创建

     

     pycharm快捷命令行创建应用和项目

    如:django-admin startproject 项目名  只书写:startproject + 项目名即可

    命令行简写:

     Django项目的启动和关闭

      一个窗口不能同时打开多个ip+post一样的项目,会报错,打开多个要修改端口号

    修改端口号:

    手动添加seething文件

     创建的应用一定要在settings中注册 才能生效  否则无法识别

    Django项目结构

    (******)
    创建的应用一定要在settings中注册 才能生效  否则无法识别
    	
    django主要文件介绍
    	项目名文件
    	  同名的项目文件夹
    		    settings.py  django暴露给用户可配置的文件
    			urls.py      路由与视图函数对应关系
    		manage.py  django入口文件
    		应用文件夹
    			migrations文件夹   数据库迁移记录
    			admin.py  django后台管理
    			apps.py   应用注册相关
    			models.py  orm模型类
    			tests.py   测试文件
    			views.py   视图函数
    

    Django基础必备三件套

    HttpResponse:返回字符串
    render:返回html页面 并且能够给该页面传值
    redirect:重定向

    具体使用方法:

    from django.shortcuts import HttpResponse, render, redirect

    HttpResponse:内部传入一个字符串参数,返回给浏览器。

    例如:
    def index(request):
        # 业务逻辑代码
        return HttpResponse("OK")

    render:类似于我们上面用到的jinja2,渲染后返回给htlm页面

    例如:
    def index(request):
        # 业务逻辑代码
        return render(request, "index.html", {"name": "alex", "hobby": ["烫头", "泡吧"]})

    redirect:

      接受一个URL参数,表示跳转到指定的URL

    def index(request):
        # 业务逻辑代码
        return redirect("/http://www.baidu.com/")

    课后练习:

    Django版登录

    启动Django报错:

    Django 启动时报错 “UnicodeEncodeError ...”

    报这个错误通常是因为计算机名为中文,改成英文的计算机名重启下电脑就可以了。

     Django 启动报错“SyntaxError: Generator expression must be parenthesized”

    报这个错很大可能是因为使用了Python3.7.0,而目前(2018-06-12)Python3.7.0和Django还有点兼容性问题,换回Python3.6的环境即可。

      

      

      

     

      

     

      

      

     

      


      

     

     

      

  • 相关阅读:
    分布式缓存重建并发冲突和zookeeper分布式锁解决方案
    C# Datatable、DataReader等转化json
    OpenResty部署nginx及nginx+lua
    zookeeper+kafka集群的安装
    缓存数据生产服务的工作流程
    实现缓存与数据库双写一致性保障
    eclipse不提示问题
    Redis 多级缓存架构和数据库与缓存双写不一致问题
    代码这样写更优雅(Python版)
    java string.getBytes(“UTF-8”) javascript equivalent
  • 原文地址:https://www.cnblogs.com/Gaimo/p/11528707.html
Copyright © 2020-2023  润新知