Day41 of learning python --web框架的本质及初识Django框架

1.web框架的本质

自己开发web框架必备的知识点
    --socket
    --http协议
    --HTML知识
    --数据库(pymysql,SQLALchemy)
HTTP:无状态,短连接
TCP:不断开
WEB应用(网站)的简单连接过程
    浏览器(socket客户端)
        2.在网站输入框输入:www.cnblogs.com
            sk.socket()
            sk.connect()
            sk.send('我想要xxx')
        5.收到
        6.连接断开

    博客园(socket服务端)
        1.监听IP和端口
        3.收到'我想要xxx'
        4.响应:'',返回想要的内容
        7.断开,等待下一个连接

网站构成的基本原理:

a.socket服务器
b.根据URL不同返回不同的内容
    路由系统:
        URL  -> 函数
c.字符串返回给用户
    模板引擎渲染:
        HTML充当模板(特殊字符)
        自己创造任意数据
    返回字符串

web框架分类:

框架种类:
    -a,b,c                  --> Tornado
    -[第三方a],b,c       --> wsgiref     -> Django
    -[第三方a],b,[第三方c]     --> flask,bottle.

两个重要的例子:

静态网站:发送给浏览器端的内容不变的,根据输入不同的网站得到不同的页面展示,可以查看URL路由系统

import socket
import time
sock = socket.socket()
sock.bind(('127.0.0.1',8080))
sock.listen(5)

def func1(request):
    with open('information.html','rb') as f:
        data = f.read()
    return data

def func2(request):
    with open('login.html','rb') as f:
        data = f.read()
    return data

def func3(request):
    with open('active.html','r',encoding='utf-8') as f:
        data = f.read()
        active_time = time.ctime()
        current_data = data.replace('@time',active_time)
    return bytes(current_data,encoding='utf-8')
relation_list = [
    ('/information.html',func1),('/login.html',func2),('/active.html',func3)
    ]

def run():
    while 1:
        conn,addr = sock.accept()  # hang 住
        #有人来连接了
        #获取用户发送的数据
        data = conn.recv(8096)
        data = str(data,encoding='utf-8')
        headers,bodys = data.split('\r\n\r\n')
        temp_list = headers.split('\r\n')
        method,url,protocal = temp_list[0].split(' ')
        conn.send(b'HTTP/1.1 200 OK\r\n\r\n')    # 此句不能少,否则浏览器不能识别,因为html的识别需要依据http协议传输才行
        func_name = None   # 要先定义了,才能使用
        for item in relation_list:
            if url == item[0]:
                func_name = item[1]
                break
        if func_name:
            response = func_name(bodys)
        else:
            response = b'404'

        conn.send(response)
        conn.close()

if __name__ =='__main__':
    run()
Python文件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>active</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <!--<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">-->
</head>
<body>
    <table border="1">
        <thead>
        <tr>
            <th>id</th>
            <th>name</th>
            <th>mail</th>
            <th>time</th>
        </tr>
        </thead>
        <tbody>
        <tr>
            <th>1</th>
            <th>alex</th>
            <th>123@qq.com</th>
            <th>@time</th>
        </tr>
        </tbody>
    </table>
<!--<script src="jQuery-3.3.1.js"></script>-->
<!--<script src="bootstrap/js/bootstrap.min.js"></script>-->
</body>
</html>
html模板,可以通过引擎渲染不同的内容.active.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>infomation</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <!--<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">-->
</head>
<h3>基本信息</h3>
<body>
    <table border="1">
        <thead>
        <tr>
            <th>id</th>
            <th>name</th>
            <th>mail</th>
            <th>time</th>
        </tr>
        </thead>
        <tbody>
        <tr>
            <th>1</th>
            <th>alex</th>
            <th>123@qq.com</th>
            <th>2019.1.19</th>
        </tr>
        </tbody>
    </table>
<!--<script src="jQuery-3.3.1.js"></script>-->
<!--<script src="bootstrap/js/bootstrap.min.js"></script>-->
</body>
</html>
information.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>login</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <!--<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">-->
</head>
<body>
<h3>Login</h3>
<form action="">
    <p>
        <label for="username">用户名:</label>
        <input type="text" id="username" name="username">
    </p>

    <p>
        <label for="password">密码:</label>
        <input type="password" id="password" name="password">
    </p>

</form>

<!--<script src="jQuery-3.3.1.js"></script>-->
<!--<script src="bootstrap/js/bootstrap.min.js"></script>-->
</body>
</html>
login.html

动态网站:从数据库中获取数据,把数据库的内容替换到html模板进行渲染,通过修改数据库的数据,从而页面展示不同的数据

import socket
import time
sock = socket.socket()
sock.bind(('127.0.0.1',8080))
sock.listen(5)

def func1(request):
    with open('information.html','rb') as f:
        data = f.read()
    return data

def func2(request):
    with open('login.html','rb') as f:
        data = f.read()
    return data

def func3(request):
    with open('active.html','r',encoding='utf-8') as f:
        data = f.read()
        active_time = time.ctime()
        current_data = data.replace('@time',active_time)
    return bytes(current_data,encoding='utf-8')


def func4(request):
    import pymysql

    # 创建连接
    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='baicells', db='school')
    # 创建游标
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

    # 执行SQL,并返回收影响行数
    effect_row = cursor.execute("select * from student ")
    user_list = cursor.fetchall()

    # 关闭游标
    cursor.close()
    # 关闭连接
    conn.close()
    print(user_list)
    """
    <tr>
        <td>%s</td>
        <td>%s</td>
        <td>%s</td>
        <td>%s</td>
    </tr>
        
    """
    content_list = []
    for row in user_list:
        tp = "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>" %(row['sid'],row['sname'],row['gender'],row['class_id'])
        content_list.append(tp)
    content = "".join(content_list)
    with open('userlist.html', 'r', encoding='utf-8') as f:
        template = f.read()
        # 模板渲染(模板+数据)
        data = template.replace('@@content@@',content)
    return bytes(data,encoding='utf-8')


# 基于第三方工具实现模板渲染
def func5(request):
    import pymysql
    from jinja2 import Template

    # 创建连接
    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='baicells', db='school')
    # 创建游标
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

    # 执行SQL,并返回收影响行数
    effect_row = cursor.execute("select * from student ")
    host_list = cursor.fetchall()
    # 关闭游标
    cursor.close()
    # 关闭连接
    conn.close()
    print(host_list)

    with open('hostlist.html', 'r', encoding='utf-8') as f:
        data = f.read()
        # 模板渲染(模板+数据)
    template = Template(data)
    data = template.render(hostlist=host_list)
    return bytes(data,encoding='utf-8')




relation_list = [
    ('/information.html',func1),('/login.html',func2),('/active.html',func3),('/mysql.html',func4),('/hostlist.html',func5)
    ]

def run():
    while 1:
        conn,addr = sock.accept()  # hang 住
        #有人来连接了
        #获取用户发送的数据
        data = conn.recv(8096)
        data = str(data,encoding='utf-8')
        headers,bodys = data.split('\r\n\r\n')
        temp_list = headers.split('\r\n')
        method,url,protocal = temp_list[0].split(' ')
        conn.send(b'HTTP/1.1 200 OK\r\n\r\n')    # 此句不能少,否则浏览器不能识别,因为html的识别需要依据http协议传输才行
        func_name = None   # 要先定义了,才能使用
        for item in relation_list:
            if url == item[0]:
                func_name = item[1]
                break
        if func_name:
            response = func_name(bodys)
        else:
            response = b'404'

        conn.send(response)
        conn.close()

if __name__ =='__main__':
    run()
Python文件,主操作
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>hostlist</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <!--<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">-->
</head>
<body>
  <table border="1">
        <thead>
        <tr>
            <th>id</th>
            <th>name</th>
            <th>gender</th>
            <th>class_id</th>
        </tr>
        </thead>
        <tbody>
            {% for row in hostlist %}
                <tr>
                    <td>{{row.sid}}</td>
                    <td>{{row.sname}}</td>
                    <td>{{row.gender}}</td>
                    <td>{{row.class_id}}</td>
                </tr>
            {% endfor %}
        </tbody>
<!--<script src="jQuery-3.3.1.js"></script>-->
<!--<script src="bootstrap/js/bootstrap.min.js"></script>-->
</body>
</html>
hostlist.html模板

2.Django框架(通过框架,主要实现业务)

1)安装,在CMD上输入:pip install django

2)创建一个Django项目:django-admin startproject mysite(可以在不同的盘内创建,例如:D:)

3)在CMD上切换到mysite目录下:cd mysite

4)启动服务器:Python manage.py runserver 127.0.0.1:8080

5)检查该简单的网站是否建立成功,打开浏览器,输入:127.0.0.1:8080,如果显示的是该页面,则已经检查成功了。

Django程序目录:
    mysite
        -settings.py         # Django配置文件
        -url.py                 # 路由系统:URL -> 函数
        -wsgi.py              #用于定义Django用的socket:wsgiref,uwsgi
        manage.py          #对当前Django程序所有操作可以基于Python manage.py   xxxx

 3.利用pycharm创建Django框架

1)创建Project

2.配置:

  模板路径:template目录,用来存放html文件的(render显示)

  静态文件路径:static  用来导入css,js,等文件的。HTML文件导入的CSS/JS文件时的文件路径前缀/static1/要与settings.py文件的STATIC_URL = '/static1/'一致

 

3.额外的配置

  在setting文件中注释掉这个字符串

Django框架例子:

Django框架的相关语句和语句
    def login(request):    # request为请求体的内容参数
        request.method
        request.POST     -> 请求体   
        request.GET      -> 请求头的url
           
       return  HttpResponse(..)
      return render(request,'login.html',{...}
      return redirect('网址')

GET请求   ->  request.GET
POST请求   -> request.GET(网址的?开始分割的数据)和request.POST
get方式提交的数据会放在url之后,以?分割url和传输数据,参数之间以&相连;post方式提交的数据会放在http包的请求体中,请求体和请求首部字段中间用一行空白相连。
get提交的数据大小有限制(因为浏览器对url的长度有限制),而post方法提交的数据没有限制
重点要学会:for循环和html结合起来,以及模板引擎中的特殊标记{{内容}}

例子:

url.py

from django.contrib import admin
from django.urls import path

from django.shortcuts import HttpResponse,render,redirect
def login(request):
    '''
    处理用户请求,并返回内容
    :param request: 用户请求相关的所有信息
    :return:
    '''
    # HttpResponse只能返回的是字符串类型的
    # return HttpResponse('login')
    # return HttpResponse('<input type="text" />')
    # 自动找到模板路径下的login.html文件,读取内容并返回给用户
    # 模板路径配置
    if request.method == "GET":
        return render(request,'login.html')
    else:
        # 用户POST 提交的数据
        # print(request.POST)
        u = request.POST.get('username')  # 不同于字典获取request.POST['username'],此不会报错
        p = request.POST.get('password')
        # 数据库连接
        import pymysql
        conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='baicells', db='userinformation')
        cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
        effect_row = cursor.execute("select * from user")
        host_list = cursor.fetchall()    # 得到的是一个带有字典的列表
        cursor.close()
        conn.close()
        print(host_list)
        for item in host_list:
            if item['name'] == u and item['password'] == p:
                # 登陆成功
                # return redirect('http://www.cnblogs.com')     # 重定向到某个页面
                return redirect('/index/')
            else:
                # 登陆失败
                return render(request,'login.html',{'error':'用户名或密码错误'})

def index(request):
    return render(request,'index.html',{'name':'alex','users':['林聪','燕子'],'user_dict':{'k1':'v1','k2':'v2'},
                                        'user_list_dict':[
                                            {'id':1,'name':'alex','email':'alex3714@163.com'},
                                            {'id':2,'name':'alex2','email':'alex3714@1632.com'},
                                            {'id': 3, 'name': 'alex3', 'email': 'alex3714@1633.com'},
                                        ]})

urlpatterns = [
    # path('admin/', admin.site.urls),
    path('login/', login),
    path('index/',index),
]

index.html  :标记语言与for循环的应用

 

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

</head>
<body>
    <h1>标记模板</h1>
    <p>{{ name }}</p>
    <P>{{ users }}</P>
    <p><h2>{{ users.0 }}</h2></p>
    <p><h2>{{ users.1 }}</h2></p>
    <p>{{ user_dict.k1 }}</p>
    <p>{{ user_dict.k2 }}</p>
    <h1>循环</h1>
    {% for item in users %}
        <p>{{ item }}</p>
    {% endfor %}
    {% for item in user_dict.values %}
        <p>{{ item}}</p>
    {% endfor %}
    <table border="1">
        <thead>
        <tr>
            <th>id</th>
            <th>name</th>
            <th>email</th>
            <th>操作</th>
        </tr>
        </thead>
    <tbody>
        {% for row in user_list_dict %}
            <tr>
                <td>{{ row.id}}</td>
                <td>{{ row.name }}</td>
                <td>{{ row.email }}</td>
                <td>
                    <a href="">编辑</a> | <a href="">删除</a>
                </td>
            </tr>
        {% endfor %}
    </tbody>

    </table>
</body>
</html>

 

login.html:Django框架的发送数据显示

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>login</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <link rel="stylesheet" href="/static1/loginStyle.css">
</head>
<body>
<h3 class="c1">用户登陆</h3>
<form action="/login/" method="POST">
    <div>
        <label for="username">用户名</label>
        <input type="text" id="username" name="username">
    </div>
    <div>
        <label for="password">密码</label>
        <input type="password" id="password" name="password">
    </div>
    {{ error }}
    <div>
        <input type="submit" value="登陆">
    </div>
<!--提交数据的时候是以字典的形式提交-->
  <!--  username:输入的username
    password:输入的密码-->
</form>

</body>
</html>

loginStyle.css样式:

.c1 {
    color: green;
}
posted on 2019-01-22 16:57  smile大豆芽  阅读(169)  评论(0)    收藏  举报