第七十四篇 web应用本质与django基础

一、web应用的本质

1.回顾

1.socket网络编程:

1.架构:C/S架构
2.协议:TCP/UDP协议
3.TCP/UDP协议属于OSI七层协议中的传输层

2.web应用:

1.架构:B/S架构
2.协议:HTTP协议
3.HTTP协议属于OSI七层协议中的应用层
4.OSI七层协议从上到下分别是:7)应用层、6)表示层、5)会话层、4)传输层、3)网络层、2)数据链路层、1)物理层。其中高层(7、6、5、4)定义了应用程序的功能,下三层(3、2、1)主要面向通过网络的端到端的数据流
5.应用层:HTTP、FTP等,对应应用程序的通信服务。表示层:加密、ASCII码,定义数据格式以及加密。会话层:SQL、rpc,控制会话。传输层:TCP、UDP,数据流复用和数据包排序。网络层:IP、IPX,定义所有结点的逻辑地址。数据链路层:mac地址。物理层:传输介质。

3.补充:

# 字符串转字节:
bytes('字符串', encoding='utf-8')

# 字节转字符串
str(b"字节", encoding='utf-8')

2.web框架的本质

1.基于B/S架构以及Http协议实现客户端与服务端交互的应用程序

2.客户端就是用户的浏览器,用于发送HTTP请求和接收服务器发来的HTTP响应

3.服务端就是socket服务端,用于接收客户端发来的HTTP请求和发送HTTP响应

二、自定义一个web框架

1.目标:将自定制的server变成一个动态的server

2.HTTP请求和HTTP响应一般都包含两个部分,第一个部分是头,第二个部分是体

3.请求头一般包含了请求的页面链接,那么服务端通过比对之后,如果有该页面,会返回状态码和页面内容

1.HTTP协议

1.简单的请求-响应协议,通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应

2.HTTP是基于客户端/服务器模式,且面向连接,典型的HTTP事务处理:1)客户端与服务器建立连接;2)客户端向服务器提出请求;3)服务器接受请求,并根据请求返回响应的文件作为应答;4)客户端与服务器关闭连接

3.HTTP请求头的内容或属性:

GET / HTTP/1.1   # 1.请求方式 根路由(连在IP地址后的网页链接) HTTP协议的版本

Host: 127.0.0.1:8080   2.IP地址(包含端口)

Connection: keep-alive  3.链接状态:保持激活

Cache-Control: max-age=0  4.缓存控制

Upgrade-Insecure-Requests: 1  5.升级加密请求
 
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36   6.用户代理(浏览器帮用户去请求服务端的代理,里面是浏览器内核)
				Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3    7.接收的文件类型
				
Accept-Encoding: gzip, deflate, br   8.接收的编码
Accept-Language: zh-CN,zh;q=0.9    9.接收的语言

4.请求头中分行使用 来写的,而两个 表示请求头结束,后面的是请求体,也就是请求内容

5.服务端发送的响应头一般会带有HTTP协议版本号、HTTP状态码,也是用两个 来将响应头和响应体隔开

http/1.1 200 ok 

 hello world

2.动态的server

1.以socket服务端为基础,通过路由系统来实现动态服务端

2.路由系统是通过将客户端请求的url映射到相对应的函数上,最后执行函数来实现的

3.实例:

# socket服务器
def run():
    import socket

    server = socket.socket()
    server.bind(('127.0.0.1', 8000))
    server.listen()  # 半连接池,有默认参数,选填

    while True:
        conn, addr = server.accept()
        data = conn.recv(1024)  

        # print(data, type(data))
        data_str = str(data, encoding='utf-8')

        header_list = data_str.split('

')

        headers = header_list[0]
        url = headers.split('
')[0].split(' ')[1]

        # 直接在源码上修改不太适合实际开发,可拓展性差
        # if url == "/index":
            # res = bytes("index", encoding='utf-8')
        # else:
            # res = bytes('404 NO FOUND', encoding='utf-8')

        # 遍历路由系统,判断之后取出对应的函数
        func_name = None
        for items in routes:
            if items[0] == url:
                func_name = items[1]
                break

        # 判断路由系统映射的函数是否存在,存在则返回相应的内容
        if func_name:
            res = func_name()
        else:
            res = bytes('404 NO FOUND', encoding='utf-8')

        conn.send(bytes("GET HTTP/1.1 200 OK

", encoding='utf-8'))
        conn.send(res)
        conn.close()
        
# 路由系统:将客户端请求的url映射到相对应的函数,最后执行函数
# 装着路由映射关系的容器(装元组的列表)
routes = [
	("/index", index),
	("/login", login),
	("/select", select),
	("/select_jinja", select_jinja),
]

# 与路由相对应的函数,可以自定义渲染引擎,也可以使用第三方工具
def index():
	return bytes('index', encoding='utf-8')

def login():
	return bytes('login', encoding='utf-8')

# 自定义规则
def select():
	import pymysql
	conn = pymysql.connect(
		host='127.0.0.1',
		user='root',
		password='123',
		database='mydb'
	)
	cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
	sql = "select * from users"
	cursor.execute(sql)
	
	users = cursor.fetchall()
	print(users)  # 是一个装着字典的列表
	
	# 我们需要在html中用@@content@@来充当占位符,以便用数据库中的数据来替换它,将数据渲染到网页上
	'''
	@@content@@ 
	替换成:
	<tr>
		<td>id</td>
		<td>name</td>
		<td>age</td>
	</tr>
	'''
	
	res_list = []
	for info in users:
		res = "<tr><td>%s</td><td>%S</td><td>%s</td></tr>" %(info['id'], info['name'], info['age'])
		res_list.append(res)
	# 将列表通过join组合成字符串
	res_str = "".join(res_list)
	
	# 读取HTML文件中的数据
	fr = open("users.html", "r", encoding="utf-8")
	data = fr.read()
	fr.close()
	
	# 将页面中@@content@@换成数据库中的内容
	data = data.replace("@@content@@", res_str)
	# 返回响应体结果
	return bytes(data, encoding='utf-8')
	
# 第三方工具jinja2
def select_jinja():
	import pymysql
	conn = pymysql.connect(
		host='127.0.0.1',
		user='root',
		password='123',
		database='mydb',
	)
	cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
	sql = "select * from users"
	cursor.execute(sql)
	users = cursor.fetchall()
	
	fr = open("users_jinja.html", "r", encoding="utf-8")
	data = fr.read()
	fr.close()
	
	# 通过jinja2这个工具来实现将数据库中的内容放到页面中
	from jinja2 import Template
	template = Template(data)
	
	data = template.render(users=users)  # users参数是HTML文件中我们需要替换的内容,我们把users这个值传过去,就可以将页面内容更改
	return bytes(data, encoding='utf-8')
	
	

3.自写web框架总结

A.先写socket服务端

B.路由系统:url ——> 函数

C.模板引擎渲染:1)自己定义的规则;2)使用第三方的工具(jinja2)

4.web框架的分类

第一种维度分类:1)A,B,C--->tornado;2)A(引入第三方),B,C --->django(wsgiref/uwsgi);3)A(引入第三方),B,C(引入第三方)--->flask

2.第二种维度分类:1)django (-orm 、-session、-form表单验证......);2)其他

三、django

1.django的安装和启动

django的安装:
	a. pip3 install django==1.11.22 -i https://pypi.tuna.tsinghua.edu.cn/simple
	b. pycharm安装
			
django的创建:
	a. django-admin startproject xxx
	b. pycharm创建 (*************)
				
django目录结构:
	根目录:
		次目录文件夹(和根目录同名):
			settings.py: 配置文件
			urls.py: 路由映射关系
	 		wsgi.py : socket服务端文件
		templates: 模板文件夹
		manage.py: 管理文件
		
启动django服务:
	pycharm启动

2.django的路由介绍

# urls.py中

# 添加路由和函数的对应关系:
urlpatterns = [
	# url(r'^admin/', admin.site.urls),
	url(r'^index/', index),
]
		
def index(request):
	return HttpResponse('index')

3.django的模板介绍

# urls.py中

# 模板渲染函数,自定义规则:

from django.shortcuts import HttpResponse, render

def index(request):  # django中映射函数需要request参数

    return HttpResponse('index')

def f1(request):
    ### 变量的渲染
    name = 'zekai'

    ### 列表
    li = ['zekai', 'lxxx', 'leijun']

    ### 字典
    dict = {"name":'zekai', 'age':18, 'hobby':'bj'}

    ### 列表中套字典
    myli = [
        {'id': 1, 'name': 'zekai', 'age': 12},
        {'id': 2, 'name': 'yuechun', 'age': 32},
        {'id': 3, 'name': 'lifu', 'age': 23}
    ]


    return render(request, 'f1.html', {"xxx":name, "li":li, 'dict':dict, 'myli':myli})  # render是关键,第三个参数是一个字典,里面是要放入页面中的数据库的数据

def f2(request):
    pass

# 路由系统
urlpatterns = [
    # url(r'^admin/', admin.site.urls),
    url(r'^index/', index),
    url(r'^f1/', f1),  
]

4.操作django时的预处理

# 以后再去创建django项目的时候, 需要做的几个操作:

# 1.到settings.py中, 配置:
	STATIC_URL = '/static/'
	STATICFILES_DIRS = (
		os.path.join(BASE_DIR, 'static'),
	)  # 逗号不能少
# 2.static目录需要创建,将非模板文件放在静态目录中,比如js、css、img等静态文件
					
				
# 3.settings.py文件中:
	MIDDLEWARE = [
		'django.middleware.security.SecurityMiddleware',
		
		'django.contrib.sessions.middleware.SessionMiddleware',
		
		'django.middleware.common.CommonMiddleware',
		
		#'django.middleware.csrf.CsrfViewMiddleware',

		'django.contrib.auth.middleware.AuthenticationMiddleware',

        'django.contrib.messages.middleware.MessageMiddleware',

		'django.middleware.clickjacking.XFrameOptionsMiddleware',
	]

# 4.
'DIRS': [os.path.join(BASE_DIR, 'templates')]

5.django的连接数据库操作

1.pymysql连接

2.django的orm连接

原文地址:https://www.cnblogs.com/itboy-newking/p/11317273.html