目录
1.web应用的本质
理论的基础
- socket网络编程
- 架构:C/S架构
- 协议:TCP/UDP协议
- 传输层协议
- web应用:
- 架构:B/S架构
- 协议:HTTP协议
- 应用层协议
- 服务端,底层的本质就是一个socket
浏览器之所以能够解析代码,是因为浏览器内置了HTML引擎,CSS引擎,JS引擎,在浏览器的内核中。
字符串与二进制之间转换
# 字符串转字节:
bytes('dbsabhdsba', encoding='utf-8')
# 字节转字符串:
str(b'asdsadadas', encoding='utf-8')
协议和端口号补充
http:80
Mysql:3306
FTP:21用于传输控制信息,20用户传输数据
SSH:22
Oracle:1521
2.自定义一个web框架
- 目标
- 将自定制的server变成一个动态的server
- 解析Http协议:
# 请求头:
# get是请求类型,/是指根目录,http是协议,1.1是版本号
GET / HTTP/1.1
Host: 127.0.0.1:8080 # 请求的ip地址
Connection: keep-alive # 保持连接
Cache-Control: max-age=0 # 缓存控制,等于0代表不过期
Upgrade-Insecure-Requests: 1 # 是否要加密
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 # 用户代理,当前是浏览器内核
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 # 服务端给客户端返回的,可以接受的一些键的类型
Accept-Encoding: gzip, deflate, br # 客户端能够接受的编码类型(压缩方式)
Accept-Language: zh-CN,zh;q=0.9\r\n\r\n # 客户端告诉服务端能够接受的语言 两个\r\n代表请求头结束
# 请求体:客户端向服务端发送的一些参数或是内容
sjflajlasdlasd
# 响应头:
HTTP/1.1 200 OK
# 响应体(用户看到的内容):
"hello world"
改造后的动态server
def f1():
return bytes('xxxx', encoding='utf-8')
def f2():
fp = open('index.html', 'r', encoding='utf-8')
data = fp.read()
return bytes(data, encoding='utf-8')
def f3():
fp = open('f3.html', 'r', encoding='utf-8')
data = fp.read()
import time
ctime = time.time()
data = data.replace("@@content@@", str(ctime))
return bytes(data, encoding='utf-8')
def f4():
import pymysql
conn = pymysql.connect(host='127.0.0.1', user='root', password='123', database='t2')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
sql = "select * from users"
cursor.execute(sql)
users = cursor.fetchall()
# print(users)
'''
将html文件中的
@@content@@
替换成
<tr>
<td>1</td>
<td>zekai</td>
<td>23</td>
</tr>
'''
res_list = []
for info in users:
### {'id': 1, 'name': 'leijun', 'age': 17},
res = "<tr><td>%s</td><td>%s</td><td>%s</td></tr>" % (info['id'], info['name'], info['age'])
res_list.append(res)
s = "".join(res_list)
### 读取html页面数据
data = open('users.html', 'r', encoding='utf-8').read()
### 替换,这个@@content@@是我们自己制定的替换规则
data = data.replace("@@content@@", s)
return bytes(data, encoding='utf-8')
def f5():
import pymysql
conn = pymysql.connect(host='127.0.0.1', user='root', password='111', database='t2')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
sql = "select * from users"
cursor.execute(sql)
users = cursor.fetchall()
print(users)
users2 = open('users2.html', 'r', encoding='utf-8').read()
#### jinja2 pip3 install jinja2
## 下面是jinja的使用方式
'''
在html中,需要用{{}}来接收,这是jinja的规则
{% for item in users %}
{{ item.id }}
{{ item.name }}
{{ item.age }}
'''
from jinja2 import Template
template = Template(users2)
data = template.render(users = users)
return bytes(data, encoding='utf-8')
# 路由系统
routes = [
('/xxx', f1),
('/ooo', f2),
('/aaa', f3),
('/kkk', f4),
('/f5', f5),
]
def run():
import socket
sock = socket.socket()
sock.bind(('127.0.0.1', 8080))
sock.listen(5)
while True:
conn, addr = sock.accept()
data = conn.recv(8090)
# print(data)
### 转成字符串类型
data_str = str(data, encoding='utf-8')
# 获取目录
header_list = data_str.split('\r\n\r\n')
headers = header_list[0]
url = headers.split('\r\n')[0].split(' ')[1]
### 判断url(太复杂)
# if url == '/xxx':
# res = bytes('xxxx', encoding='utf-8')
# elif url == '/ooo':
# res = bytes('oooo', encoding='utf-8')
# else:
# res = bytes('404 not 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 not found', encoding='utf-8')
conn.send(bytes("HTTP/1.1 200 OK\r\n\r\n",encoding='utf-8'))
conn.send(res)
conn.close()
if __name__ == '__main__':
run()
- 路由系统: 将客户端请求的url映射到相对应的函数, 最后执行函数即可
总结:
'''
自己写web框架:
a. 自己写socket服务端
b. 路由系统:
url ====》 函数
c. 模板引擎渲染
1. 自己定义的规则
2. 使用第三方的工具(jinja2)
'''
web框架的分类
- 第一种维度分类(借用上面总结的序号):
- a, b, c ----> tornado
- a(引入第三方),b,c -----> django (wsgiref/uwsgi)
- a(引入第三方), b, c(引入第三方) ------> flask
- 第二种维度分类
- django
- 自带:
- orm
- session
- form表单验证
- ......
- 其它
- django
django
- 一个强大的web框架
django的安装和启动
django的安装:
- cmd中输入
pip3 install django==1.11.22
(注意添加版本号,这个版本比较稳定,当前最新是2.x版本,但是bug较多) -----> 推荐 - pycharm安装
django的创建:
- cmd中输入
django-admin startproject 文件名
(在你cmd的目录下创建) - pycharm创建 -----> 推荐
- 注意:创建好之后不要乱改
django目录结构
- 文件名以day54为例
- 创建好之后不要乱改名字
|-day54
|- day54
|- settings.py:配置文件
|- urls.py:路由映射关系
|- wsgi.py:socket服务端文件
|- manage.py:管理文件
|- templates:模版文件,比如html就是模版文件
|- status:存放一些静态文件(静态资源)
|- css
|- js
|- img
- 注意:django的启动,是在pycharm的上方启动那个文件夹名的东西
django的路由介绍
# 在urls.py文件中
# 参数一定要写request
def index(request):
return HttpResponse('index')
# url中填写的是一个正则表达式
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^index/', index),
]
django的模版介绍
- 从数据库中取出来数据,传到网页上,称之为渲染,模版渲染,其中模版是html页面。
- 渲染:将服务端处理好的东西,渲染到客户端,网页中
# 模版渲染函数
# python
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}
]
# 在settings中已经进行了路径配置,可以直接写templates中的html文件
return render(request, 'f1.html',
{"xxx":name, "li":li, 'dict':dict, 'myli':myli})
<!-- html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Title</title>
</head>
<body>
{# 变量渲染 #}
<h2>{{ xxx }}</h2>
{#列表的渲染#}
<ul>
<li>{{ li.0 }}</li>
<li>{{ li.1 }}</li>
<li>{{ li.2 }}</li>
</ul>
<hr>
{#列表的循环#}
<ul>
{% for items in li %}
<li>{{ items }}</li>
{% endfor %}
</ul>
{#字典的渲染#}
<h3>{{ dict.age }}</h3>
{#字典的循环#}
<ul>
{% for items in dict.values %}
<li>{{ items }}</li>
{% endfor %}
</ul>
<ul>
{% for items in dict.keys %}
<li>{{ items }}</li>
{% endfor %}
</ul>
<ul>
{% for key, val in dict.items %}
<li>{{ key }} --- {{ val }}</li>
{% endfor %}
</ul>
{#列表中套字典格式#}
<table border="1px">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
</tr>
</thead>
<tbody>
{% for items in myli %}
<tr>
<td>{{ items.id }}</td>
<td>{{ items.name }}</td>
<td>{{ items.age }}</td>
<td><a href="/f2/">删除</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
创建django项目的时候,需要做的几个操作
# 到settings.py中, 配置:
# 1. 最后
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
# 逗号不能少,只能是STATICFILES_DIRS,不能修改
# static目录需要创建
# 2. MIDDLEWARE中
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',
]
#3. TEMPLATES中
'DIRS': [os.path.join(BASE_DIR, 'templates')]
学一下FTP协议还有SMTP。
阿帕奇是什么
重新去复习一下url
hexo+gitee搭建博客
什么叫路由,什么叫接口
django中的函数不是串行的,url中的参数,默认只会传一个request,可以用括号控制参数。括号里的内容,就是参数内容,几个括号,几个参数。