zoukankan      html  css  js  c++  java
  • day59---初识django框架

    Django框架认知(一)

    http/https/websocket

    # http协议:超文本传输协议,具有以下特性:
    (1)基于request和response;
    (2)基于TCP/IP并作用于应用层之上的协议;
    (3)无状态,不保存用的状态信息;
    (4)无链接/短链接
    http协议的数据传输是明文,默认端口80
    # https协议:是以安全为目的的安全通道,即http+ssl,传输的数据是加密的(通过ssl完成加密),默认端口443
    # websocket:一种基于TCP的新型网络协议
    

    http数据格式

    请求首行
    请求头
    
    
    请求体
    """
    GET /index HTTP/1.1
    
    Host: 182.xx.xx.34:9090
    
    Connection: keep-alive
    
    Upgrade-Insecure-Requests: 1
    
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36
    
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    Purpose: prefetch
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9
    
    
    
    
    """
    

    一个web框架的简单雏形

    import socket
    from threading import Thread
    
    IP_ADDRESS = ('0.0.0.0', 9090)
    BUF_SIZE = 8096
    
    
    class MyServer(object):
        def __init__(self, ip_address):
            self.ip_address = ip_address
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
        def bind(self):
            self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.server.bind(self.ip_address)
    
        def listen(self):
            self.server.listen(5)
    
        def accept(self):
            return self.server.accept()
    
        @staticmethod
        def communicate(conn, addr):
            print(f'收到[{addr[0]}:{addr[1]}]的链接请求')
            while True:
                data = conn.recv(BUF_SIZE).decode('utf-8')
                conn.send(b'HTTP/1.1 200 OK
    Content_Type: text/html; charset=utf-8
    
    ')
                visit_path = data.split(' ')[1]
                print(visit_path)
                print(data.split(' '))
                if visit_path == '/index':
                    res = 'hello, i am index!'
                elif visit_path == '/home':
                    res = 'hello, i am home'
                else:
                    res = '404 , not found page'
                conn.send(bytes(res, encoding='utf-8'))
                conn.close()
    
        def run(self):
            self.bind()
            self.listen()
            while True:
                conn, addr = self.accept()
                t = Thread(target=self.communicate, args=(conn, addr))
                t.start()
    
    
    if __name__ == '__main__':
        s = MyServer(IP_ADDRESS)
        s.run()
    

    上述示例中传输的是普通的字符串,我们也可以传输带有html标签的文本,甚至是文件,随着功能的扩展,我们需要将都写在一个文件中显然是不合适的,我们将文件进行拆分成,ulrs.py,views.py,mysocket.py

    urls.py: 路由与视图的对应关系
    views.py:视图函数
    mysocket.py: 处理socket请求
    

    urls.py

    """路由与视图的一一对应关系"""
    from views import *
    
    urls = [
        ('/index',index),
        ('/home',home),
    ]
    

    views.py

    """处理业务逻辑"""
    def index():
        res = '<h1>hello world</h1>'
        return res
    
    
    def home():
        res = '<a href="http://www.mzitu.com/" target="_blank">look</a>'
        return res
    
    

    mysocket.py

    import socket
    from threading import Thread
    from urls import urls
    from views import *
    
    IP_ADDRESS = ('0.0.0.0', 9090)
    BUF_SIZE = 8096
    
    
    class MyServer(object):
        def __init__(self, ip_address):
            self.ip_address = ip_address
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
        def bind(self):
            self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.server.bind(self.ip_address)
    
        def listen(self):
            self.server.listen(5)
    
        def accept(self):
            return self.server.accept()
    
        @staticmethod
        def communicate(conn, addr):
            print(f'收到[{addr[0]}:{addr[1]}]的链接请求')
            while True:
                data = conn.recv(BUF_SIZE).decode('utf-8')
                conn.send(b'HTTP/1.1 200 OK
    Content_Type: text/html; charset=utf-8
    
    ')
                visit_path = data.split(' ')[1]
                func = None
                for url in urls:
                    if url[0] == visit_path:
                        func = url[1]
                        break
                if func:
                    res = func()
                else:
                    res = '404 not found page'
                conn.send(bytes(res, encoding='utf-8'))
                conn.close()
    
        def run(self):
            self.bind()
            self.listen()
            while True:
                conn, addr = self.accept()
                t = Thread(target=self.communicate, args=(conn, addr))
                t.start()
    
    
    if __name__ == '__main__':
        s = MyServer(IP_ADDRESS)
        s.run()
    
    

    借助于wsgiref模块来实现

    静态HTML文件的显示

    urls.py

    from views import*
    
    urls = [
        ('/index',index),
        ('/home',home),
    ]
    

    views.py

    def index(environ):
        pass
    
    def home(environ):
        pass
    

    text1.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta http-equiv="content-type" charset="UTF-8">
        <title>test1</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <style>
            a{
                text-decoration: none;
            }
        </style>
    </head>
    <body>
    <a href="http://www.mzitu.com/" target="_blank">福利链接1</a>
    </body>
    </html>
    

    text2.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta http-equiv="content-type" charset="UTF-8">
        <title>test2</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <style>
            a{
                text-decoration: none;
            }
        </style>
    </head>
    <body>
    <a href="http://www.baidu.com" target="_blank">福利链接2</a>
    </body>
    </html>
    

    myserver.py

    from wsgiref.simple_server import make_server
    from views import *
    from urls import urls
    
    
    def run(environ, start_response):
        """
        environ:请求相关的所有数据,一个大字典
        start_response:响应相关的所有数据
        return:返回给浏览器的数据
        """
        start_response('200 OK',[('Content_Type','text/html'),])
        func = None
        for url in urls:
            if url[0] == environ.get('PATH_INFO'):
                func = url[1]
                break
        if func:
            res = func(environ)
        else:
            res = '404,not page found!'
        return [bytes(res,encoding='utf-8'),]
    
    
    
    if __name__ == '__main__':
        s = make_server('0.0.0.0', 9090, run)
        s.serve_forever()
    

    动态html文件的显示

    (1)从后端返回一个字典给用户

    urls.py

    from views import *
    
    urls = [
        ('/home',home),
    ]
    

    views.py

    from jinja2 import Template
    
    def home(environ):
        user_info = {'name': 'jason', 'age': 18, 'hobby': 'dbj'}
        with open('active1.html', mode='r', encoding='utf-8') as f:
            data = f.read()
        tmp = Template(data)
        res = tmp.render(user=user_info)
        return res
    

    active1.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta http-equiv="content-type" charset="UTF-8">
        <title>active1</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    </head>
    <body>
    {{ user }}  /*获取user字典*/
    {{ user.get('name')}} /*获取属性name的值*/
    {{ user['age']}} /*获取属性age的值*/
    {{ user.hobby }} /*获取属性hobby的值*/
    </body>
    </html>
    

    myserver.py没有变动

    (2)后端从数据库拿到数据返回给前端进行展示

    urls.py

    from views import *
    
    urls = [
        ('/index',home),
    ]
    

    views.py

    from jinja2 import Template //模板语法
    import pymysql
    
    
    def index(environ):
        conn = pymysql.connect(
            host='0.0.0.0',
            port=3306,
            user='root',
            password='123456',
            database='day59',
            charset='utf8',
            autocommit=True,
        )
        cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
        sql = "SELECT * FROM user"
        affect_rows = cursor.execute(sql)
        data_list = cursor.fetchall()
        with open('active1.html', mode='r', encoding='utf-8') as f:
            data = f.read()
        tmp = Template(data)
        res = tmp.render(user_list=data_list)
        return res
    
    

    active1.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta http-equiv="content-type" charset="UTF-8">
        <title>active1</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcdn.net/ajax/libs/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">
                <h1 class="text-center">用户数据</h1>
                <table class="table table-hover table-striped">
                    <thead>
                        <tr>
                            <th>ID</th>
                            <th>NAME</th>
                            <th>AGE</th>
                            <th>HOBBY</th>
                        </tr>
                    </thead>
                    <tbody>
                        {% for user_dict in user_list %}
                        <tr>
                            <td>{{user_dict.id}}</td>
                            <td>{{user_dict.name}}</td>
                            <td>{{user_dict.age}}</td>
                            <td>{{user_dict.hobby}}</td>
                        </tr>
                        {% endfor %}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
    </body>
    </html>
    

    wsgiref模块的详细分析

    流程1:浏览器请求、wsgiref解析封装数据、urls路由分发、views视图逻辑处理、返回模版html页面、wsgiref打包封装、交给浏览器展示数据。
    
    流程2:浏览器请求、wsgiref解析封装数据、urls路由分发、views视图逻辑处理、调用数据库数据、渲染到模版html页面上、返回模版html页面、wsgiref打包封装、交给浏览器展示数据。
    

    wsgiref其实给我们干了两件事情:

    (1)按照http请求协议解析数据
    (2)按照http响应协议来组织数据
    

    python的三大主流框架介绍

    (1)Django框架

    python最出名的web框架,它最出名的是其全自动化的管理后台:只需要使用起ORM,做简单的对象定义,它就能自动生成数据库结构、以及全功能的管理后台。
    

    特点:大而全,有时候过于笨重

    (2)FLASK

    一个用python写的轻量级web框架,
    

    特点:自带功能特别少,第三模块特别多,依赖性严重(第三方模块)

    (3)tornado

    特点:异步非阻塞,支持高并发

    我们将一个框架分为以下3个模块:

    """
    A:socket部分(用于解析http请求,组织相关的数据按照http格式响应)
    B: 路由与视图函数的一一对应关系
    C:模板语法
    """
    

    三种框架的对比

    A 部分 B部分 C部分
    Django 用的wsgiref模块 用的自己的 用的自己的
    FLASK werkzeug(内部还是 wsgiref模块) 用的自己的 jinja2
    tornado 用的自己写的 用的自己写的 用的自己写的

    Django框架的安装

    Linux安装

    pip install django==1.11.29
    

    创建一个django项目

    # 使用django-admin startproject xx项目名
    [root@alisurpass project]# django-admin startproject wpsite
    
    # 创建一个应用 python manage.py startapp app名称
    [root@alisurpass wpsite]# python manage.py startapp app01
    
    # 创建静态文件夹static和HTML存放文件夹templates
    [root@alisurpass wpsite]# mkdir -p static templates
    
    # 修改项目中的配置文件
    (1)注册app
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01.apps.App01Config',  #全写,可以简写‘app01’
    ]
    
    (2)添加访问的主机
    ALLOWED_HOSTS = ['*'] #使得所有主机度可以访问,为了防止非法入侵,这里可以设置访问的IP 如['182.92.59.34','127.0.0.1']
    
    (3)TEMPLATES里面添加模板的path
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')], #添加path
            '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',
                ],
            },
        },
    ]
    
    (4) 添加静态文件路径
    STATIC_URL = '/static/'
    
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR,'static'),
    )
    

    然后我们就可以启动django项目了

    [root@alisurpass wpsite]# python manage.py runserver 0.0.0.0:9090
    

    目录如下

    .
    ├── app01
    │   ├── admin.py    #django后台管理
    │   ├── apps.py     #注册使用
    │   ├── __init__.py
    │   ├── migrations  #数据库迁移记录
    │   │   ├── __init__.py
    │   │   └── __pycache__
    │   │       └── __init__.cpython-38.pyc
    │   ├── models.py   #数据库相关 模型类(orm)
    │   ├── __pycache__
    │   │   ├── admin.cpython-38.pyc
    │   │   ├── apps.cpython-38.pyc
    │   │   ├── __init__.cpython-38.pyc
    │   │   └── models.cpython-38.pyc
    │   ├── tests.py    #测试文件
    │   └── views.py    #视图函数(视图层)
    ├── db.sqlite3
    ├── manage.py        #Django的入口文件
    ├── static
    ├── templates
    └── wpsite
        ├── __init__.py
        ├── __pycache__
        │   ├── __init__.cpython-38.pyc
        │   ├── settings.cpython-38.pyc
        │   ├── urls.cpython-38.pyc
        │   └── wsgi.cpython-38.pyc
        ├── settings.py    #配置文件
        ├── urls.py        #路由与视图函数的一一对应关系
        └── wsgi.py        #wsgiref模块
    
    8 directories, 22 files
    
    

    Django三大核心命令

    httpResponse

    def index(request):
        #业务逻辑代码
        return HttpResponse('<a href="http://www.mzitu.com/" target="_blank">hello</a>')
    

    redirect

    def home(request):
        return redirect("http://www.mzitu.com/")
    

    render

    """
    render方法可接收三个参数:
    一是request参数;
    二是待渲染的html模板文件;
    三是保存具体数据的字典参数。
    """
    def hello(request):
        return render(request,'hello.html')
    

  • 相关阅读:
    ARM Linux 3.x的设备树(Device Tree)
    ubuntu 14.04 编译内核出现unable to locate package ncurses-devel 问题的解决
    Device Tree Usage( DTS文件语法)
    Ubuntu 14.04中gedit打开文件出现中文乱码问题
    Jenkins中集成jmeter-maven插件
    Linux(centos6.5)下安装jenkins
    IM系统架构设计之浅见
    一些常用软件的网络端口协议分类介绍
    Jenkins执行批处理文件失败
    八大持续集成工具
  • 原文地址:https://www.cnblogs.com/surpass123/p/12939399.html
Copyright © 2011-2022 走看看