zoukankan      html  css  js  c++  java
  • python之路_初识django框架

    一、WEB框架介绍

      互联网刚兴起的那段时间大家都热衷于CS架构,也就是Client/Server模式。每个用户的电脑上安装一个Client,就像QQ这种终端软件。随着互联网的发展,开发客户端显得越来越‘重’,BS架构(Browser/Server模式)越来越流行,也就是用户只需要一个浏览器就足够了。

    1、页面显示的过程

    2、HTTP协议

      所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端。用户的浏览器一输入网址,会给服务端发送数据,那浏览器会发送什么数据?怎么发?这个谁来定?HTTP协议。HTTP协议就是解决这个问题,它规定了发送消息和接收消息的格式

      每个HTTP请求和响应都遵循相同的格式,一个HTTP包含Header和Body两部分,其中Body是可选的。HTTP响应的Header中有一个Content-Type表明响应的内容格式。如text/html表示HTML网页。
    (1)HTTP请求

      HTTP GET请求的格式:

      HTTP POST请求格式:

    (2)HTTP响应

      HTTP响应的格式:

    3、自定义WEB框架

      WEB应用本质就是一个sockect服务端,只要让我们的Web框架在给客户端回复响应的时候按照HTTP协议的规则加上响应头,这样我们就实现了一个正经的Web框架。如下简单实例:开启服务端后,在浏览器上输入网址:127.0.0.1:8090/index/后就会向浏览器返回:这是主页内容

    from socket import socket
    server=socket()
    server.bind(("127.0.0.1",8090))
    server.listen(5)
    while True:
        conn,addr=server.accept()
        data = conn.recv(1024).decode()                                                      #data为请求的HTTP格式
        print(data)
        header=data.split("
    
    ")[0]                                                     #获得请求header部分
        temp=header.split("
    ")[0]                                                         #获得header中包含请求路径的第一行
        url=temp.split(" ")[1]                                                               #获得请求路径
        conn.send(b'HTTP/1.1 200 OK
    Content-Type:text/html; charset=utf-8
    
    ')       #返回HTTP响应格式内容
    #根据路径不同返回不同的内容
        if url=="/index/":
            response="这是主页"
        else:
            response="404"
        conn.send(bytes(response,encoding="utf-8"))

    如下为上述实例接收到HTTP请求的data内容:

    GET /index/ HTTP/1.1                                              #header部分
    Host: 127.0.0.1:8090
    Connection: keep-alive
    Cache-Control: max-age=0
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36
    Upgrade-Insecure-Requests: 1
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9
    
    
    GET /favicon.ico HTTP/1.1                                         #body部分
    Host: 127.0.0.1:8090
    Connection: keep-alive
    Pragma: no-cache
    Cache-Control: no-cache
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36
    Accept: image/webp,image/apng,image/*,*/*;q=0.8
    Referer: http://127.0.0.1:8090/index/
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9

      上述实例我们可以从请求头里面拿到请求的URL,然后做一个判断,我们的Web服务根据用户请求的URL不同而返回不同的内容。但是问题又来了,如果有很多很多页面怎么办?难道要挨个判断?当然不用,我们有更聪明的办法。

    from socket import socket
    server=socket()
    server.bind(("127.0.0.1",8090))
    server.listen(5)
    def index():
        return "这是主页"
    def info():
        return "这是个人信息页"
    func_list=[
        ("/index/",index),
        ("/info/",info)
      ]
    while True:
        conn,addr=server.accept()
        data = conn.recv(1024).decode()
        header=data.split("
    
    ")[0]
        temp=header.split("
    ")[0]
        url=temp.split(" ")[1]
        conn.send(b'HTTP/1.1 200 OK
    Content-Type:text/html; charset=utf-8
    
    ')
        func_name=None
        for i in func_list:
            if url==i[0]:
                func_name=i[1]
                break
    
        if func_name:
            response=func_name()
        else:
            response="404"
        conn.send(bytes(response,encoding="utf-8"))

      完美解决了不同URL返回不同内容的问题。但是我不想仅仅返回几个字符串,我想给浏览器返回完整的HTML内容,这又该怎么办呢?没问题,不管是什么内容,最后都是转换成字节数据发送出去的。我可以打开HTML文件,读取出它内部的二进制数据,然后发送给浏览器。

    from socket import socket
    server=socket()
    server.bind(("127.0.0.1",8090))
    server.listen(5)
    def index():
        with open("index.html",encoding="utf-8") as f:
            data_html=f.read()                                         #读取html程序,本质是字符串
        import pymysql
        conn = pymysql.connect(host='localhost', user='root', password='', database='day65', charset='utf8')
        cur = conn.cursor(cursor=pymysql.cursors.DictCursor)           # 设置查询结果以字典形式显示
        sql = "select id,name,balance from user"
        cur.execute(sql)
        use_list = cur.fetchall()
        print(use_list)#[{'id': 1, 'name': 'egon', 'balance': 10000}, {'id': 2, 'name': 'alex', 'balance': 2000}, {'id': 3, 'name': 'wsb', 'balance': 20000}]
        ret=""
        for i in use_list:
            ret+="""
             <tr>
                <td>{0}</td>
                <td>{1}</td>
                <td>{2}</td>
            </tr>
            """.format(i["id"],i["name"],i["balance"])
        cur.close()
        conn.close()
        data_new=data_html.replace("@@xx@@",ret)                        #将html中的占位内容用数据库中查询的结果组成的字符替换
        return data_new                                                 #返回替换数据的html字符串
    
    index()
    def info():
        return "这是个人信息页"
    func_list=[
        ("/index/",index),
        ("/info/",info)
        ]
    while True:
        conn,addr=server.accept()
        data = conn.recv(1024).decode()
        header=data.split("
    
    ")[0]
        temp=header.split("
    ")[0]
        url=temp.split(" ")[1]
        conn.send(b'HTTP/1.1 200 OK
    Content-Type:text/html; charset=utf-8
    
    ')
        func_name=None
        for i in func_list:
            if url==i[0]:
                func_name=i[1]
                break
        if func_name:
            response=func_name()
        else:
            response="404"
        conn.send(bytes(response,encoding="utf-8"))

      上述代码模拟了一个web服务的本质,而对于真实开发中的Python Web程序来说,一般分为两部分:服务器程序和应用程序。服务器程序负责对Socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理。应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架。

      不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。这样,服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对于服务器还是框架,都是不好的。对服务器来说,需要支持各种不同框架,对框架来说,只有支持它的服务器才能被开发出的应用使用。这时候,标准化就变得尤为重要。一旦标准确定,双方根据约定的标准各自进行开发即可。WSGI(Web Server Gateway Interface)就是这样一种规范,它定义了使用Python编写的Web APP与Web Server之间接口格式,实现Web APP与Web Server间的解耦。

    二、django框架

    1、框架介绍

      根据第一部分内容介绍,我们可以总结出一个web框架应该包含如下三部分:a.sockect服务、b.根据不同的url调用不同函数(包含逻辑)、c.返回内容(模板渲染)。常见的python WEB框架有tornado(包含如上3部分, Django(上述a部分为第三方的),flask(上述a和c为第三方的)。

    2、Django安装

      Django框架安装:

      命令行创建django项目(首先将cd到django项目欲放置的位置):

      命令行开启django服务端(首先将cd到django项目文件夹的位置):

    python manage.py runserver 

      上述开启的服务的默认端口为:127.0.0.1:8000,如果需要指定端口,则在上述命令后空格直接跟指定的ip和端口

     3、目录介绍

    4、配置文件

      模板文件配置:在python中创建一个django项目后,在项目文件夹下会多一个templates文件夹,主要用于存放html模板文件,若要准确找到引用的html文件,需要在setting文件中对此文件夹路径进行配置。如下:

      静态文件配置:在使用html模板文件时,其通常会有使用js或css等文件,这些文件称为静态文件,为了使其正常生效,我们也需要在setting文件进行相关配置,如下:

      html文件中引用静态文件的方式如下:

    5、入门三件套

      (1)HttpResponse:用于向服务端返回字符串,如启动服务后,在浏览器请求:127.0.0.1:8000/index/后,浏览器显示hello world字符内容

    from django.conf.urls import url
    from django.contrib import admin
    from django.shortcuts import HttpResponse
    def index(request):
        return HttpResponse("hello world")
    
    urlpatterns = [
        # url(r'^admin/', admin.site.urls),
        url(r'^index/', index),
        ]

      (2)render:用于渲染html文件,如启动服务后,在浏览器请求:127.0.0.1:8000/login/后,浏览器会显示login.html文件应被渲染出的结果

    from django.conf.urls import url
    from django.contrib import admin
    from django.shortcuts import render                   #render用于渲染html文件
    def login(request):                                   #request就代表了请求的所有内容
        return render(request,"login.html")
    
    urlpatterns = [
        # url(r'^admin/', admin.site.urls),
        url(r'^login/', login),
        ]

       (3)redirect:用于跳转到指定的连接,实例如下:当启动服务端后,在浏览器请求:127.0.0.1:8000/login/后,会显示login.html被渲染的登录界面,提交后若判断登录成功,则会跳转到指定的网页。

    login.html文件主要代码:

    <body>
    <h1>欢迎登录</h1>
    <form action="/login/" method="post">                           //action为提交路径,action为请求方式
        <p><input type="text" name="username"></p>
        <p><input type="password" name="userpswd"></p>
        <p><input type="submit" value="提交"></p>
        {{ error_msg }}                                             //模板语言,不传值不会显示
    </form>
    </body>

    项目中url逻辑代码:

    from django.conf.urls import url
    from django.contrib import admin
    from django.shortcuts import HttpResponse,render,redirect
    def login(request):
        if request.method=="GET":                 #request.method表示请求类型
            return render(request,"login.html")
        else:#当点击提交按钮执行
            print(request.method)                 #结果:POST
            print(request.POST)                   #结果为登录输入的用户名及密码<QueryDict: {'uesername': ['zhangli'], 'userpswd': ['123']}>
            if request.POST.get("username")=="zhangli" and request.POST.get("userpswd")=="123":
                return redirect("http://www.baidu.com") #如果登录成功,则跳转其他页面
            else:
                return render(request, "login.html", {"error_msg": "用户名或密码错误"})       #有html有模板语言(占位用)时render用法
    urlpatterns = [
        # url(r'^admin/', admin.site.urls),
        url(r'^login/', login),
        ]

    6、模板语言

      主要用于html文件中,暂时主要介绍两种:用于实现循环和占位,占位已在上一节展示,此处不再演示,主要介绍循环模板,如下例:

    index.html文件主要代码:

    <body>
    
    <table border="1">
        <thead>
        <tr>
            <th>#</th>
            <th>姓名</th>
            <th>工资</th>
        </tr>
        </thead>
        <tbody>
            {% for i in user_list %}
                <tr>
                <td>{{ i.id }}</td>
                <td>{{ i.name }}</td>
                <td>{{ i.balance }}</td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
    </body>

    项目中url代码:

    from django.conf.urls import url
    from django.contrib import admin
    from django.shortcuts import HttpResponse,render,redirect
    def index(request):
        import pymysql
        conn = pymysql.connect(host="127.0.0.1", port=3306, user="root", passwd="", db="day65", charset="utf8")
        cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
        cursor.execute("select id, name, balance from user")
        user_list = cursor.fetchall()
        cursor.close()
        conn.close()
        print(user_list)#查询结果为:[{'id': 1, 'name': 'egon', 'balance': 10000}, {'id': 2, 'name': 'alex', 'balance': 2000}, {'id': 3, 'name': 'wsb', 'balance': 20000}]
        return render(request, "index.html", {"user_list": user_list})
    
    urlpatterns = [
        # url(r'^admin/', admin.site.urls),
        url(r'^login/', login),
        url(r'^index/', index),
        ]

      







      

  • 相关阅读:
    ORACLE 当字段中有数据如何修改字段类型
    ORACLE 语句
    对接支付宝支付接口开发详细步骤
    生成uuid
    DataGrip如何连接和移除MySQL数据库
    iOS提交AppStore被拒原因
    swift系统学习第二章
    swift系统学习第一章
    iOS开发:JavaScriptCore.framework的简单使用--JS与OC的交互篇
    iOS开发:微信支付
  • 原文地址:https://www.cnblogs.com/seven-007/p/7892274.html
Copyright © 2011-2022 走看看