• django启动前的安装


    一:web框架基础简介

    【1】web框架本质

      (1)web本质也是C/S架构 

      (2)浏览器:客户端

      (2)服务端:服务端

    【2】web框架自定义

    复制代码
    import socket
    server = socket.socket()
    server.bind(('127.0.0.1',8080))
    server.listen(6)
    
    
    while True:
        conn ,addr = server.accept()
        # 字符串
        recv_data = conn.recv(1024).decode('utf-8')
        print(recv_data)
        conn.send(b'hello world')
        conn.close()

    复制代码

    (1)客户端结果展示

    (2)服务端结果展示

    复制代码
    '''b'GET / HTTP/1.1
    Host: 127.0.0.1:8080
    Connection: keep-alive
    Cache-Control: max-age=0
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
    Sec-Fetch-Mode: navigate
    Sec-Fetch-User: ?1
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
    Sec-Fetch-Site: none
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
    
    '''
    复制代码

    PS:客户端无法正常接收数据的原因

    (1)首先浏览器向服务端发送请求的时候 这个数据怎么发送 格式是什么样式

    (2)不同的网站可能对发送方式定义的不一样 如果太多不一样 导致整个互联网紊乱

    (3)因此我们使用同一标准HTTP协议

    【3】HTTP协议版本

    复制代码
    import socket
    server = socket.socket()
    server.bind(('127.0.0.1',8080))
    server.listen(6)
    
    
    while True:
        conn ,addr = server.accept()
        # 字符串
        recv_data = conn.recv(1024)
        # HTTP版本 响应状态码 换行符
        conn.send(b'HTTP/1.1 200 OK
    
    ')
        conn.send(b'hello world')
        conn.close()
    复制代码

    二:Web框架修正版

    【1】根据用户请求的url不同返回相应的数据

    (1)作用:每个用户可能请求的数据不同 根据用户请求的结果不同 返回不同的数据

    (2)思路:

      (1)首先需要获取用户输入的路径

      (2)获取用户的路径根据不同的路径做不同从处理

    例如:

    import socket
    
    server = socket.socket()
    server.bind(('127.0.0.1', 8080))
    server.listen(6)
    
    while True:
        conn, addr = server.accept()
        # 拿到用户传入的数据 将其转为字符串状态
        recv_data = conn.recv(1024).decode('utf-8')
        print(recv_data)  # 字符串
        
        # 将获取的字符串进行切割获取列表
        path_list = recv_data.split('
    ')[0]
        
        # 列表取索引获取访问路径
        current_path = path_list.split(' ')[1]
        
        print(current_path)  # /index
    
        # 根据HTTP协议进行数据交互
        conn.send(b'HTTP/1.1 200 OK
    
    ')
    
        # 根据访问路径不同 返回不同的结果
        if current_path == '/index':
            conn.send(b'index')
        elif current_path == '/home':
            conn.send(b'home')
    
        #     访问资源不存 返回404
        else:
            conn.send(b'404 error')
    根据路径不同获取不同的响应结果
    '''
    D:Softwarespython3.6python.exe "E:/work station/day51/django基础版本.py"
    
    请求首行
    GET / HTTP/1.1  
    
    请求头
    Host: 127.0.0.1:8080
    Connection: keep-alive
    Cache-Control: max-age=0
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
    Sec-Fetch-Mode: navigate
    Sec-Fetch-User: ?1
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
    Sec-Fetch-Site: cross-site
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
    
    
    
    
    请求体:用户没传入
    
       # conn.send(b'HTTP/1.1 200 OK 
    
    ')
    服务端接受的字符串数据

    【2】路由与视图函数对应关系

    (1)作用:

      (1)上述代码解决了根据不同的url返回不同的结果

      (2)但是假如有多个条件语句 需要写大量的条件判断 这样肯定是不合理的

    (2)解决办法

      (1)创建路由与函数的对应关系 通过路由来执行不同的功能

    例如:

    import socket
    
    server = socket.socket()
    server.bind(('127.0.0.1', 8080))
    server.listen(6)
    
    
    def index(current_path):
        response = f'hello{current_path}'
        # 将字符串转换成二进制传输
        return bytes(response,encoding='utf-8')
    
    
    def home(current_path):
        response = f'hello{current_path}'
        return bytes(response, encoding='utf-8')
    
    # 创建路由与视图函数关系 以后添加新的功能 直接添加路由与对应的视图函数即可
    url_list = [
        ('/index', index),
        ('/home', home)
    ]
    
    while True:
        conn, addr = server.accept()
        # 拿到用户传入的数据 将其转为字符串状态
        recv_data = conn.recv(1024).decode('utf-8')
    
        # 将获取的字符串进行切割获取列表
        path_list = recv_data.split('
    ')[0]
    
        # 列表取索引获取访问路径
        current_path = path_list.split(' ')[1]
    
        # 根据HTTP协议进行数据交互
        conn.send(b'HTTP/1.1 200 OK
    
    ')
    
        func = None
        #  循环打印上述路由与视图关系列表
        for url in url_list:
            # 如果用户的url路径在上述列表中
            if url[0] == current_path:
                # 给上述函数赋值
                func = url[1]
                # 函数赋值之后 不需要再继续进行循环 直接打印即可
                break
        # 如果上函数被赋值  则调用函数
        if func:
            res = func(current_path)
        else:
            res = b'404 error'
    
        # 返回消息给客户端
        conn.send(res)
        conn.close()

    三:动静态网页传递

    (1)定义:

      (1)静态网页:数据是固定不变的

      (2)动态网页:数据是是可灵活变化的

    (2)作用:

      (1)在上述代码中我们返回一些无用的字符串呈现给用户

      (2)在网页传递过程中我们传递相应的HTML文件呈现给用户

    例如:

    import socket
    
    server = socket.socket()
    server.bind(('127.0.0.1', 8080))
    server.listen(60)
    
    
    def index():
        # 对于python来说什么文件都是二进制 直接读取发送即可
    
        with open(r'ht1.html', 'rb') as file:
            data = file.read()
            return data
    
    
    def home():
        with open(r'ht1.html', 'rb') as file:
            data = file.read()
            return data
    
    
    url_dict = {
        '/index': index,
        '/home': home
    }
    
    while True:
        conn, addr = server.accept()
        recv_data = conn.recv(1024).decode('utf-8')
        url_list = recv_data.split('
    ')[0]
        url_path = url_list.split(' ')[1]
    
        conn.send(b'HTTP/1.1 200 OK
    
    ')
        func = None
        for key, value in url_dict.items():
            if key == url_path:
                func = url_dict.get(key)
                break
    
        if func:
            res = func()
    
        else:
            res = b'404 error'
    
        conn.send(res)
        conn.close()
    import socket
    
    server = socket.socket()
    server.bind(('127.0.0.1', 8080))
    server.listen(66)
    from datetime import datetime
    
    func = None
    
    
    def index():
        now_time = datetime.now().strftime('%Y-%m-%d %X')
        with open(r'h2.html', 'r', encoding='utf-8') as f:
            data = f.read()
    
            # 读取HTML中的数据 将其替换成我们想要传给用户的数据 这样类似于我们将后端数据插入到HTML数据中
            time = data.replace('SR', now_time).encode('utf-8')
            return time
    
    
    def home():
        now_time = datetime.now().strftime('%Y-%m-%d %X')
        with open(r'h2.html', 'r', encoding='utf-8') as f:
            data = f.read()
    
            # 读取HTML中的数据 将其替换成我们想要传给用户的数据 这样类似于我们将后端数据插入到HTML数据中
            time = data.replace('SR', now_time).encode('utf-8')
            return time
    
    
    url_list = {
        '/index': index,
        '/home': home
    }
    
    while True:
        conn, addr = server.accept()
        recv_data = conn.recv(1024).decode('utf-8')
        conn.send(b'HTTP/1.1 200OK
    
    ')
        # 获取url地址
        url_path = recv_data.split('
    ')[0].split(' ')[1]
    
        for key, value in url_list.items():
            if key == url_path:
                func = url_list.get(key)
                break
        if func:
            res = func()
        else:
            res = b'404 error'
    
        conn.send(res)
        conn.close()
    动态网页

    四:服务器程序和应用程序

    对于真实开发中的python web程序来说,一般会分为两部分:服务器程序和应用程序。

    服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理。

    应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架,例如:Django、Flask、web.py 等。不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。

    这样,服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对于服务器还是框架,都是不好的。对服务器来说,需要支持各种不同框架,对框架来说,只有支持它的服务器才能被开发出的应用使用。

    这时候,标准化就变得尤为重要。我们可以设立一个标准,只要服务器程序支持这个标准,框架也支持这个标准,那么他们就可以配合使用。一旦标准确定,双方各自实现。这样,服务器可以支持更多支持标准的框架,框架也可以使用更多支持标准的服务器。

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

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

     

    五:WSGI/jinja2基本使用方式

    【1】wsgi

    (1)作用:

      (1)可以利用该模块替换我们自己写的socket server部分

      (2)将客户端传入的数据拆封成字典

      (3)将服务端传入给客户端的数据封装携带含有HTTP协议

    例如:

    # 导入模块
    from wsgiref.simple_server import make_server
    
    
    def index():
        data = b'hello world!'
        return data
    
    
    def home():
        data = b'hello world!'
        return data
    
    
    url_list = {
        '/index': index,
        '/home': home
    }
    
    
    def run_server(request, response):
        '''
        与客户端进行数据交互的函数
        :param request: 用户请求数据
        :param response: 服务端回应数据
        :return:
        '''
        print(request)  # 用户传来的数据自动变成字典格式
        response('200 ok', [])  # 回应客户端的格式
    
        url_path = request.get('PATH_INFO')
        func = None
        for key,value in url_list.items():
            if key == url_path:
                func = url_list.get(key)
                break
        if func:
            res = func()
        else:
            res = b'404 error'
    
        return [res]
    
    
    
    if __name__ == '__main__':
        # 监听该地址加上端口号 如果有请求 直接调用该函数
        server = make_server('127.0.0.1', 8080, run_server)
        # 启动服务端
        server.serve_forever()
    wsgiref的使用方式

    【2】jinja2与html结合

    (1)作用:将后端传递给前端的数据进行页面渲染

    例如:

    import pymysql
    from jinja2 import Template
    from wsgiref.simple_server import make_server
    
    
    
    def mysql():
        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 user_info"
        affect_rows = cursor.execute(sql)
        data = cursor.fetchall()
        with open(r'my_sql.html','r',encoding='utf-8') as f:
            recv_data = f.read()
        temp = Template(recv_data)
        res = temp.render(user_list=data).encode('utf-8')
        return res
    
    
    url_list = {
        '/mysql': mysql,
    
    }
    
    
    
    def run(request, response):
        url_path = request['PATH_INFO']
        response('200 ok', [])
        func = None
        for key, value in url_list.items():
            if key == url_path:
                func = url_list.get(key)
                break
    
        if func:
    
            res = func()
        else:
            res = b'404 error'
    
        return [res]
    
    
    if __name__ == '__main__':
        server = make_server('127.0.0.1', 8080, run)
        print('启动')
        server.serve_forever()
    jinja2与数据库
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    </head>
    <body>
    <div class="container">
    
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <h2 class="text-center">用户数据展示</h2>
                <table class="table table-hover table-bordered table-striped">
                    <thead>
                    <tr>
                        <th class="text-center">id</th>
                        <th class="text-center">username</th>
                        <th class="text-center">age</th>
                    </tr>
                    </thead>
                    <tbody>
                    {%for user_dict in user_list%}
                    <tr>
                        <td class="text-center">{{user_dict.id}}</td>
                        <td class="text-center">{{user_dict.name}}</td>
                        <td class="text-center">{{user_dict.age}}</td>
                    </tr>
                    {%endfor%}
                    </tbody>
                </table>
            </div>
    
        </div>
    </div>
    
    </body>
    </html>
    前端

    六:Django安装使用

    【1】命令行安装启动

    (1)Django安装

    pip3 install django=1.11.11

    (2)检查Django是否安装成功

    Django-admin

    (3)创建Django项目

    Django-admin startproject + 项目名称

    (4)Django目录介绍

    复制代码
    mysite/
    ├── manage.py  # 管理文件
    └── mysite  # 项目目录
        ├── __init__.py
        ├── settings.py  # 配置
        ├── urls.py  # 路由 --> URL和函数的对应关系
        └── wsgi.py  # runserver命令就使用wsgiref模块做简单的web server
    复制代码

    (5)创建Django应用

    django-admin startapp  + 应用名
    python manage.py startapp +  应用名

    (6)目录应用介绍

    复制代码
    └──  migrations     # 数据库迁移记录
        ├── admin.py    # 后台管理
        ├── apps.py     # 应用注册相关
        ├── models.py   # orm模型类
        └── test.py     # 测试文件
        └── views.py    # 视图函数
    复制代码

    (6)启动Django服务

    Django-admin manage.py runserver

     

     PS:

    (1)命令行创建Django项目不会自动生成templates文件夹

    (2)settings配置文件中也需要修改

    (3)创建的项目需要在配置文件注册生效 否则无识别

    七:Django基础三件套

    from django.shortcuts import HttpResponse, render, redirect

    (1)HttpResponse

    作用:内部输入字符串 返回给浏览器

    例如:

    def index(request):
        # 业务逻辑代码
        return HttpResponse("hello world")

    (2)render

    作用:

    (1)接受一个需要渲染的文件以及字典

    (2)将数据填充进模板文件 返回给前端

    例如:

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

    PS:其前端接受取值 只能通过.的方式进行取值

    (3)redirect

    作用:接受一个url地址 跳转到另外一个地址

    例如:

    def index(request):
        # 业务逻辑代码
        return redirect("/home/")

    八:Web简易数据通讯过程

  • 相关阅读:
    暑假周总结02
    音乐播放器
    setInterval、控制停止和继续
    暑假周总结01
    ul li、a标签的下划线
    innerHTML、document获取对象、className修改样式
    领扣(LeetCode)N叉树的层序遍历 个人题解
    领扣(LeetCode)两句话中的不常见单词 个人题解
    领扣(LeetCode)二叉树的中序遍历 个人题解
    领扣(LeetCode)用队列实现栈 个人题解
  • 原文地址:https://www.cnblogs.com/asdaa/p/11528916.html
Copyright © 2020-2023  润新知