Django准备知识-web应用、http协议、web框架、Django简介

1、web应用

  Web应用程序是一种能够经过web访问的应用程序(web应用本质是基于socket实现的应用程序),程序的最大好处是用户很容易访问应用程序,用户只须要有浏览器便可,不须要再安装其余软件。应用程序有两种模式C/S、B/S。C/S是客户端/服务器端程序,也就是说这类程序通常独立运行。而B/S就是浏览器端/服务器端应用程序,这类应用程序通常借助谷歌,火狐等浏览器来运行。WEB应用程序通常是B/S模式。Web应用程序首先是“应用程序”,和用标准的程序语言,如java,python等编写出来的程序没有什么本质上的不一样。在网络编程的意义下,浏览器是一个socket客户端,服务器是一个socket服务端。html

       以下代码是一个python写的服务端代码,能够用浏览器当客户端去访问该服务端,理解web服务:java

  import socket
  def handle_request(conn):
      request_data = conn.recv(1024)
      print("request_data: ", request_data)  # 观察并分析request_data值

      conn.send("HTTP/1.1 200 OK\r\nstatus: 200\r\nContent-Type:text/html\r\n\r\n<h1>Hello, World!</h1>".encode("utf8"))
               # 响应首行         \r\n响应头(能够有多个键值对,以\r\n分隔)    \r\n\r\n响应体

  def main():
      sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      sock.bind(('localhost', 8812)) 
      sock.listen(5)
      while True:
          print("the server is waiting for client-connection....")
          conn, addr = sock.accept()
          handle_request(conn)
          conn.close()

  if __name__ == '__main__':
      main()

2、http协议

一、http协议简介

       HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于万维网(WWW:World Wide Web)服务器与本地浏览器之间传输超文本的传送协议。python

  HTTP是一个属于应用层的面向对象的协议,因为其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,通过几年的使用与发展,获得不断地完善和扩展。HTTP协议工做于客户端-服务端架构上。浏览器做为HTTP客户端经过URL向HTTP服务端即WEB服务器发送全部请求。Web服务器根据接收到的请求,向客户端发送响应信息。mysql

二、http协议特性

  (1)基于TCP/IP      web

              HTTP协议是基于TCP/IP协议之上的应用层协议。sql

  (2)基于请求-响应模式shell

    HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,确定是先从客户端开始创建通讯的,服务器端在没有接收到请求以前不会发送响应。数据库

  (3)无状态保存django

    HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议自身不对请求和响应之间的通讯状态进行保存。也就是说在HTTP这个级别,协议对于发送过的请求或响应都不作持久化处理。编程

    使用HTTP协议,每当有新的请求发送时,就会有对应的新响应产生。协议自己并不保留以前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,而特地把HTTP协议设计成如此简单的。但是,随着Web的不断发展,因无状态而致使业务处理变得棘手的状况增多了。好比,用户登陆到一家购物网站,即便他跳转到该站的其余页面后,也须要能继续保持登陆状态。针对这个实例,网站为了可以掌握是谁送出的请求,须要保存用户的状态。HTTP/1.1虽然是无状态协议,但为了实现指望的保持状态功能,因而引入了Cookie技术。有了Cookie再用HTTP协议通讯,就能够管理状态了。有关Cookie的详细内容稍后讲解。

       (4)无链接

              无链接的含义是限制每次链接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开链接。采用这种方式能够节省传输时间。

三、http请求协议与响应协议

       http协议包含由浏览器发送数据到服务器须要遵循的请求协议与服务器发送数据到浏览器须要遵循的响应协议。用于HTTP协议交互的信被为HTTP报文。请求端(客户端)的HTTP报文作请求报文,响应端(服务器端)的作响应报文。HTTP报文自己是由多行数据构成的字符串文本。

       (1)请求协议

              请求格式,如图:

              请求方式:get与post

                     a、GET提交的数据会放在URL中的路径以后,以?分割路径和传输数据,参数之间以&相连,如EditBook?name=test&pwd=123;POST方法是把提交的数据放在HTTP包的请求体中;

                     b、GET提交的数据大小有限制(由于浏览器对URL的长度有限制),而POST方法提交的数据没有限制(即POST方法才有请求体);

                     c、GET与POST请求在服务端获取请求数据方式不一样;

              示例:GET / HTTP/1.1\r\n Host: 127.0.0.1:8812\r\nUser-Agent: Mozilla/5.0...\r\n\r\n

       (2)响应协议

              响应格式,如图:

    示例:HTTP/1.1 200 OK\r\nstatus:200\r\nContent-Type:text/html\r\n\r\n<h1>Hello</h1>

    响应状态码:状态码的职责是当客户端向服务器端发送请求时, 描述返回的请求结果。借助状态码,用户能够知道服务器端是正常处理了请求,仍是出现了错误。状态码(如:200 OK)以3位数字和缘由短语组成。数字中的第一位指定了响应类别,后两位无分类。响应类别有如下5种:

       演示实例:

  import socket

  sock = socket.socket()
  sock.bind(("127.0.0.1",8808))
  sock.listen(5)

  while 1:
      print("server waiting.....")
      conn,addr = sock.accept()
      data = conn.recv(1024)
      print("request-data",data)
      # 读取html文件
      with open("login.html","rb") as f:
          data = f.read()

      conn.send((b"HTTP/1.1 200 OK\r\n\r\n%s"%data))
      conn.close()

       login.html文件:

  <!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <title>Title</title>
  </head>
  <body>

  <form action="" method="post">
      用户名 <input type="text" name="user">
      密码 <input type="password" name="pwd">
      <input type="submit">
  </form>

  </body>
  </html>

3、web框架

       Web框架(Web framework)是一种开发框架,用来支持动态网站、网络应用和网络服务的开发。大多数的web框架提供了一套开发和部署网站的方式,也为web行为提供了一套通用的方法。web框架已经实现了不少功能,开发人员使用框架提供的方法而且完成本身的业务逻辑,就能快速开发web应用了。浏览器和服务器的是基于HTTP协议进行通讯的。也能够说web框架就是在以上十几行代码基础上扩展出来的,有不少简单方便使用的方法,大大提升了开发的效率。

一、wsgiref模块

       最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回。

  若是要动态生成HTML,就须要把上述步骤本身来实现。不过,接收HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,若是咱们本身来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。

  正确的作法是底层代码由专门的服务器软件实现,咱们用Python专一于生成HTML文档。由于咱们不但愿接触到TCP链接、HTTP原始请求和响应格式,因此,须要一个统一的接口协议来实现这样的服务器软件,让咱们专心用Python编写Web业务。这个接口就是WSGI:Web Server Gateway Interface。而wsgiref模块就是python基于wsgi协议开发的服务模块

       阅读以下代码,理解wsgiref模块用法:

from wsgiref.simple_server import make_server

def application(environ, start_response):
    """
    environ:wsgiref 模块帮咱们封装好的请求信息字典
    start_response:用来封装响应格式
    """
    print(environ)
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [b'<h1>Hello, web!</h1>']

httpd = make_server('', 8080, application)

print('Serving HTTP on port 8080...')
# 开始监听HTTP请求,内部封装好了socket,等待客户端来链接,当有请求进来的时候执行application函数:
httpd.serve_forever()

       总结:wsgiref模块的主要做用是拆请求协议的包和封装响应格式

二、DIY一个web框架

       目录结构以下:

    import pymysql

    conn = pymysql.connect(host='127.0.0.1',port= 3306,user = 'root',password='',db='mydb')
    cur = conn.cursor()

    sql='''
        create table userinfo(
            id INT PRIMARY KEY,
            name VARCHAR(32),
            password VARCHAR(32)
    )

    '''
    cur.execute(sql)

    conn.commit()

    cur.close()
    conn.close()
    
models.py文件
    from wsgiref.simple_server import make_server

    from app01.views import *
    import urls

    def routers():
    URLpattern = urls.URLpattern
        return URLpattern

    def applications(environ,start_response):
        path = environ.get("PATH_INFO")
        start_response('200 OK', [('Content-Type', 'text/html'),('Charset', 'utf8')])
        urlpattern = routers()
        func = None
        for item in urlpattern:
            if path == item[0]:
                func = item[1]
                break
        if func:
            return [func(environ)]
        else:
            return [b"<h1>404!<h1>"]

    if __name__ == '__main__':
        server = make_server("",8080,applications)
        print("Serving HTTP on port 8080...")
        server.serve_forever()
manage.py(启动文件)
    from app01.views import *

    URLpattern = (
        ("/login/", login),
    )
urls.py文件
    import pymysql

    from urllib.parse import parse_qs

    def login(environ):
        if environ.get("REQUEST_METHOD") == "POST":

            try:
                request_body_size = int(environ.get('CONTENT_LENGTH', 0))
            except (ValueError):
                request_body_size = 0

            request_body = environ['wsgi.input'].read(request_body_size)
            data = parse_qs(request_body)

            user = data.get(b"user")[0].decode("utf8")
            pwd = data.get(b"pwd")[0].decode("utf8")

            # 链接数据库
            conn = pymysql.connect(host='127.0.0.1',port= 3306,user = 'root',password='',db='mydb') 
            # 建立游标
            cur = conn.cursor()
            SQL = "select * from userinfo WHERE NAME ='%s' AND PASSWORD ='%s'"%(user,pwd)
            cur.execute(SQL)

            if cur.fetchone():
                f = open("templates/backend.html","rb")
                data = f.read()
                data = data.decode("utf8")
                return data.encode("utf8")
            else:
                 print("OK456")
                 return b"user or pwd is wrong"

        else:
            f = open("templates/login.html", "rb")
            data = f.read()
            f.close()
            return data
views文件  
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>

    <h4>登陆页面</h4>
    <form action="" method="post">
         用户名 <input type="text" name="user">
         密码 <input type="text" name="pwd">
        <input type="submit">
    </form>

    </body>
    </html>
login.html文件
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h4>welcome to myweb!</h4>
    </body>
    </html>
backend.html文件

       myweb这个package就是一个web框架,下载这个web框架就能够快速实现一些简单的web功能,好比查看时间。

4、Django简介

一、MVC与MTV模型

       a、MVC

              Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的、松耦合的方式链接在一块儿,模型负责业务对象与数据库的映射(ORM),视图负责与用户的交互(页面),控制器接受用户的输入调用模型和视图完成用户的请求,其示意图以下所示:

 

       b、MTV

    Django的MTV模式本质上和MVC是同样的,也是为了各组件间保持松耦合关系,只是定义上有些许不一样,Django的MTV分别是指:

                M 表明模型(Model): 负责业务对象和数据库的关系映射(ORM)。

      T 表明模板 (Template):负责如何把页面展现给用户(html)。

      V 表明视图(View):   负责业务逻辑,并在适当时候调用Model和Template。

    除了以上三层以外,还须要一个URL分发器,它的做用是将一个个URL的页面请求分发给不一样的View处理,View再调用相应的Model和Template,MTV的响应模式以下所示:

 

    通常是用户经过浏览器向咱们的服务器发起一个请求(request),这个请求会去访问视图函数,(若是不涉及到数据调用,那么这个时候视图函数返回一个模板也就是一个网页给用户),视图函数调用模型,模型去数据库查找数据,而后逐级返回,视图函数把返回的数据填充到模板中空格中,最后返回网页给用户。

二、Django的下载与基本命令

       (1)下载Django

    pip3  install  django            # 不写版本号,默认下载最新版本

    pip3  install  django==2.1.2    # 指定版本

       (2)建立一个django project(django-admin.exe所在目录要加入环境变量)

              django-admin  startproject  mysite

         注意:此命令在哪一个目录下执行,django项目就建在了哪一个目录下

              执行后,当前目录会生成mysite的工程,目录结构以下:

    manage.py -- Django项目里面的工具,经过它能够调用django shell和数据库等。

              settings.py -- 包含了项目的默认设置,包括数据库信息,调试标志以及其余一些工做的变量。

              urls.py -- 负责把URL模式映射到应用程序。

       (3)在mysite目录下建立应用(必定要先进入manage.py所在目录,再执行以下命令)

              python  manage.py  startapp  blog

    注意:一个项目中有多个应用,每一个应用都有本身的业务逻辑

    执行后,mysite目录下会生成blog这个应用,目录以下:

        (4)启动django项目(不写端口,默认是8000)

              python  manage.py  runserver  8080

              这样咱们的django就启动起来了!当咱们访问:http://127.0.0.1:8080/时就能够看到:

三、基于Django实现的一个简单示例

       urls文件(url控制器):

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

    from blog import views

    urlpatterns = [
        path(r'^admin/$', admin.site.urls),
        path(r'^index/$', views.index),
    }

       views文件(视图):

  from django.shortcuts import render

  # Create your views here.
  import datetime

  def index(request):
      now = datetime.datetime.now()
      ctime = now.strftime("%Y-%m-%d %X")
      return render(request,"index.html",{"ctime":ctime})

       index.html(模板文件)- 若没有templates目录则手动建立,其中放html文件

  <!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <title>Title</title>
  </head>
  <body>

  <h4>当前时间:{{ ctime }}</h4>

  </body>
  </html>

       经过浏览器访问127.0.0.1:8080/index/,查看效果。

  注意:每个视图函数都传一个request形参,封装了请求协议,并返回HttpResponse对象。

5、补充

一、url的组成      

  协议://域名:端口号/路径?参数(键值对,如:user=name&pwd=123)

       示例:https://www.baidu.com:80/s?wd=alex

二、Django框架问题

       用命令建立完成后没有templates文件夹(存放html文件),须要手动建立,而且有些版本没有配置templates路径,需手动配置,方法以下:

       找到settings.py文件中的TEMPLATES列表中的 'DIRS': [os.path.join(BASE_DIR, "templates")]

三、forbidden问题

  当使用django时,若是页面遇到forbidden错误时(post提交容易发生),就去settings.py文件中找到MIDDLEWARE列表的第3项'django.middleware.csrf.CsrfViewMiddleware',将其注释掉便可。

相关文章
相关标签/搜索