Django基础了解知识

HTTP协议(超文本传输协议)

HTTP协议

  1. 四大特性

    1. 基于TCP/IP之上作用于应用层

    2. 基于请求响应

    3. 无状态 引申出cookie session token……

    4. 无连接

      长连接 websocket (HTTP协议的大补丁)

  2. 数据格式:

    1. 请求格式

      1. 请求首行(请求方式,协议版本等等)
      2. 请求头(一大堆K:V键值对)
      3. \r\n 或者是\n 总之就是加一个空行
      4. 请求体(真正的数据 发post请求的时候才有 如果是get请求不会有)
    2. 响应格式
      1. 响应首行
      2. 响应头
      3. \r\n 或者是\n总之就是加一个空行
      4. 响应体(真正的数据 发post请求的时候才有 如果是get请求不会有)
    3. 响应状态码
      • 用特定的数字表示一些意思

        • 1XX:服务端已经成功接收到了你的数据 表示数据正在处理 你可以继续提交其他数据
        • 2XX:服务端成功响应(200请求成功)
        • 3XX:重定向(没登录淘宝,点击搜索商品,会跳转到登录页面,这就是重定向)
        • 4XX:请求错误(404 请求资源不存在 403 拒绝访问)
        • 5XX:服务器内部错误(500等)
  3. 请求方式

    • get方式:朝别人要数据
  • post请求:向别人提交数据(eg:用户登录)

    • url:统一资源定位符

自定义web框架

主要是以下两个过程:

  1. 手动书写socket
  2. 手动处理http格式数据
## 说明
'''
我的理解是:
web框架本质就是一个基于socket的客户端和服务端进行通信,交互的过程,也就是C/S架构,其实由于是通过浏览器向服务端发送请求和响应,所以应该是B/S架构,但是浏览器(Browser)本质也是一个客户端。
如果按照一般的网络编程套路来,会报错,这是因为浏览器端走的是HTTP协议,但是服务端发过来的数据是基于TCP/UDP协议的,所以就不能识别数据而报错。
所以我们需要在发消息的时候加一个HTTP的格式标准,这样就可以在浏览器端实现正常打印, 这是由于HTTP和TCP是不同层的协议,首先传输层的是TCP,只负责传输数据,发过去就进行接收打印二进制,但是在服务端发送的是支持TCP协议的,这样在浏览器端就会报错而无法正常显示(因为浏览器支持的是HTTP协议)
''' ## 代码
import socket server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5) """
请求首行
b'GET /index HTTP/1.1\r\n
请求头
Host: 127.0.0.1:8080\r\n
Connection: keep-alive\r\n
Cache-Control: max-age=0\r\n
DNT: 1\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36\r\n
Sec-Fetch-Mode: navigate\r\n
Sec-Fetch-User: ?1\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n
Sec-Fetch-Site: none\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
\r\n
请求体
' #请求体是空的,因为浏览器发送的是get请求,请求体只在post请求时才会有。
""" while True:
conn, addr = server.accept()
data = conn.recv(1024)
# print(data) #打印出来的是浏览器发送过来的HTTP请求数据
conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
# conn.send(b'hello')
data = data.decode('utf-8')
current_path = data.split('\r\n')[0].split(' ')[1]
# print(current_path)
if current_path == '/index': # 如果浏览器上输入的后缀是/index, 那么将.html文件读出来发送过去
# conn.send(b'index')
with open(r'index.html','rb') as f:# # 这里面用document.charset看一下网页的编码格式,不然的话可能会乱码。
conn.send(f.read())
elif current_path == '/login':
conn.send(b'login')
else:
conn.send(b'404 error')
conn.close()

类型转换

data = b'hello s11'

# 二进制转字符串
data = str(data, encoding='utf-8')
print(data,type(data)) # 字符串转二进制
data = bytes(data, encoding='utf-8')
print(data,type(data))

基于wsgiref模块

什么是wsgi

​ 该模块实现了自定义web框架的两个过程

​ 根据功能不同拆分成了不同的py文件

​ 拆分完成之后 如果想要添加功,仅仅只需要在urls.py以及views.py中修改就可以了

  1. urls.py 路由与视图函数对象关系
  2. views.py 放的是视图函数 (处理业务逻辑的,函数或者类)
  3. templates 模板文件夹 (一堆html文件)
## 基于wsgiref.py

'''
(主要作用就是初始化服务端,然后接受浏览器端发过来的请求,把请求分门别类,传给urls找到对应的视图函数,然后在views中执行相应的视图函数并把结果返回到前端页面)
''' from wsgiref.simple_server import make_server
from urls import urls
from views import * def run(env,response):
"""
:param env: 请求相关的所有数据
:param response: 响应相关的所有数据
:return:
"""
response('200 OK',[])
print(env)
current_path = env.get('PATH_INFO')
# if current_path == '/index':
# # 很多业务逻辑代码
# return [b'index']
# elif current_path == '/login':
# return [b'login']
# else:
# return [b'404 error']
# 先定义一个变量名 用来存储后续匹配到的函数名
func = None
# for循环 匹配后缀
for url in urls:
if current_path == url[0]:
func = url[1] # 一旦匹配成功 就将匹配到的函数名赋值给func变量
break # 主动结束匹配
# 判断func是否有值
if func:
res = func(env)
else:
res = error(env)
return [res.encode('utf-8')] if __name__ == '__main__':
server = make_server('127.0.0.1',8081,run)
# 实时监听该地址 只要有客户端来连接 统一交给run函数去处理
server.serve_forever() # 启动服务端 ## urls.py
'''
主要作用就是用一个存有元组的列表,实现将前端接收到的后缀名与view中的函数进行对应,其实就相当于一个路由分发器,中转驿站
''' from views import * urls = [
('/index',index),
('/login',login),
('/xxx',xxx),
('/get_time',get_time),
('/get_user',get_user),
('/get_db',get_db),
] # views.py
'''
用于处理业务逻辑,其实就相当于之前写的项目中的interface接口,主要根据前端接收过来的数据 然后执行相应的函数,实现相应的功能,并将结果返回给前端展现出来。
''' def index(env):
return 'index' def login(env):
return 'login' def error(env):
return '404 error' def xxx(env):
return 'xxx' from datetime import datetime def get_time(env):
current_time = datetime.now().strftime('%Y-%m-%d %X')
with open(r'E:\Python11\10月\1018\代码\web框架推导\templates\get_time.html','r',encoding='utf-8') as f:
data = f.read()
data = data.replace('$$time$$',current_time)
return data from jinja2 import Template def get_user(env):
d = {'name':'jason','pwd':'123','hobby':['read','running','music']}
with open(r'E:\Python11\10月\1018\代码\web框架推导\templates\get_user.html','r',encoding='utf-8') as f:
data = f.read()
temp = Template(data)
res = temp.render(user=d) # 将字典d传递给前端页面
# 页面上通过变量名user就能够获取到该字典
return res import pymysql def get_db(env):
conn = pymysql.connect(
host = '127.0.0.1',
port = 3306,
user = 'root',
password = 'root',
database = 'hupu',
charset = 'utf8',
autocommit = True
)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
sql = "select * from user_info1"
cursor.execute(sql)
res = cursor.fetchall()
print(res)
with open(r'E:\Python11\10月\1018\代码\web框架推导\templates\get_db.html','r',encoding='utf-8') as f:
data = f.read()
temp = Template(data)
ret = temp.render(user_list = res) # 将字典d传递给前端页面 页面上通过变量名user就能够获取到该字典
return ret ### 前端代码 ##get_db.html <!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.3.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.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-bordered table-striped table-hover">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>pwd</th>
</tr>
</thead>
<tbody>
{% for user_dict in user_list %}
<tr>
<td>{{ user_dict.id }}</td>
<td>{{ user_dict.name }}</td>
<td>{{ user_dict.pwd }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div> </div>
</body>
</html> ## get_time.html <!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.3.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
</head>
<body>
$$time$$
</body>
</html> ## get_user.html
<!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.3.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<p>{{ user }}</p>
<p>{{ user.name }}</p>
<p>{{ user['pwd'] }}</p>
<p>{{ user.get('hobby') }}</p>
</body>
</html>

注意1:

上面代码也实现了动静态网页的功能,那么什么是动态网页什么是静态网页呢?

静态网页:简单来说就是写死的网页,随着html代码的生成,页面的内容和显示效果就基本上不会发生变化了——除非你修改页面代码。

动态网页:页面代码虽然没有变,但是显示的内容却是可以随着时间、环境或者数据库操作的结果而发生改变的。主要体现在两种情况:1. 后端获取当前时间展示到前端;2.后端获取数据库中的数据展示到前端

注意2:

如何将后端获取的数据 传递给html页面?

后端获取的数据 传递给html页面 专用名词>>>: 模板的渲染

import jinja2就可以实现上述功能:

pip3 install jinja2

	模板语法(极其贴近python后端语法)
<p>{{ user }}</p>
<p>{{ user.name }}</p>
<p>{{ user['pwd'] }}</p>
<p>{{ user.get('hobby') }}</p> {% for user_dict in user_list %} ##在前端页面中使用后端的循环语法
<tr>
<td>{{ user_dict.id }}</td>
<td>{{ user_dict.name }}</td>
<td>{{ user_dict.pwd }}</td>
</tr>
{% endfor %}

自定义web框架(django)的更多相关文章

  1. web 框架的本质及自定义web框架 模板渲染jinja2 mvc 和 mtv框架 Django框架的下载安装 基于Django实现的一个简单示例

    Django基础一之web框架的本质 本节目录 一 web框架的本质及自定义web框架 二 模板渲染JinJa2 三 MVC和MTV框架 四 Django的下载安装 五 基于Django实现的一个简单 ...

  2. day48:django前戏之HTTP协议&自定义web框架

    目录 1.HTTP协议 1.HTTP协议简介 2.HTTP协议概述 3.HTTP协议工作原理 4.HTTP协议请求方法 5.HTTP协议状态码 6.URL 7.HTTP请求格式 8.HTTP响应格式 ...

  3. python运维开发(十七)----jQuery续(示例)web框架django

    内容目录: jQuery示例 前端插件 web框架 Django框架 jQuery示例 dom事件绑定,dom绑定在form表单提交按钮地方都会绑定一个onclick事件,所有查看网站的人都能看到代码 ...

  4. Python 17 web框架&Django

    本节内容 1.html里面的正则表达式 2.web样式简介 3.Django创建工程 Html里的正则表达式 test 用来判断字符串是否符合规定的正则       rep.test('....')  ...

  5. Python自定义web框架、Jinja2

    WSGI(Web Server Gateway Interface)是一种规范,它定义了使用python编写的web app与web server之间接口格式,实现web app与web server ...

  6. python web框架 django wsgi 理论

    django wsgi python有个自带的wsgi模块 可以写自定义web框架 用wsgi在内部创建socket对象就可以了 自己只写处理函数就可以了django只是web框架 他也不负责写soc ...

  7. python web框架 django 工程 创建 目录介绍

    # 创建Django工程django-admin startproject [工程名称] 默认创建django 项目都会自带这些东西 django setting 配置文件 django可以配置缓存 ...

  8. Web框架——Django笔记

    Web框架--Django笔记 MVC和MTV MVC:Model.View.Controller MTV:Model.Template.View Django--MTV 1.创建Django程序   ...

  9. Python3.5学习十八 Python之Web框架 Django

    Python之Web框架: 本质:Socket 引用wsgiref创建web框架 根据web框架创建过程优化所得: 分目录管理 模板单独目录 执行不同函数单独存入一个方法py文件 Web框架的两种形式 ...

随机推荐

  1. LeetCode236. 二叉树的最近公共祖先

    * @lc app=leetcode.cn id=236 lang=cpp  *  * [236] 二叉树的最近公共祖先  *  * https://leetcode-cn.com/problems/ ...

  2. webapi使用ExceptionFilterAttribute过滤器

    文章 public class ApiExceptionFilterAttribute:ExceptionFilterAttribute { public override void OnExcept ...

  3. ulimit 用法和系统优化

    ulimit :用于shell启动进程所占用的资源 -a:显示目前资源限制的设定: -c <core文件上限>:设定core文件的最大值,单位为区块: -d <数据节区大小>: ...

  4. Codeforces Round #596 (Div. 2, based on Technocup 2020 Elimination Round 2) F. Tree Factory 构造题

    F. Tree Factory Bytelandian Tree Factory produces trees for all kinds of industrial applications. Yo ...

  5. IM开发者的零基础通信技术入门(三):国人通信方式的百年变迁

    [来源申明]本文原文来自:微信公众号“鲜枣课堂”,官方网站:xzclass.com,原题为:<中国通信的百年沉浮>,本文引用时已征得原作者同意.为了更好的内容呈现,即时通讯网在收录时内容有 ...

  6. 把ping的结果写入文件

    写一个sh文件: #!/bin/bash while true do $|>&` done 保存成ping.sh,赋可执行权限: chmod +x ping.sh 执行: sh ./pi ...

  7. JavaScript DOM 常用操作

    1.理解DOM: DOM(Document Object Model ,文档对象模型)一种独立于语言,用于操作xml,html文档的应用编程接口. 怎么说,我从两个角度理解: 对于JavaScript ...

  8. jQuery 源码分析(五) map函数 $.map和$.fn.map函数 详解

    $.map() 函数用于使用指定函数处理数组中的每个元素(或对象的每个属性),并将处理结果封装为新的数组返回,该函数有三个参数,如下: elems Array/Object类型 指定的需要处理的数组或 ...

  9. C# 消息队列之 RabbitMQ 进阶篇

    Ø  简介 在之前的 C# 消息队列之 RabbitMQ 基础入门 中介绍了 RabbitMQ 的基本用法,其实要更全面的掌握 RabbitMQ 这个消息队列服务,我们还需要掌握以下内容: 1.   ...

  10. Kubernetes 有状态与无状态介绍

    Kubernetes 有状态与无状态介绍 无状态:deployment - 认为所有pod都是一样的,不具备与其他实例有不同的关系. - 没有顺序的要求. - 不用考虑再哪个Node运行. - 随意扩 ...