Django二转Day02
http
#1 http 是什么
#2 http特点
#3 请求协议详情
-请求首行---》请求方式,请求地址,请求协议版本
-请求头---》key:value形式
-referer:上一次访问的地址
-user-agenet:客户端类型
-name:lqz
-cookie:只要是当前域【https://www.cnblogs.com/】中有的cookie,当次请求就会携带
-请求体:get请求一般没有请求体
#4响应协议详情
-响应首行:响应协议版本,响应状态码,响应描述
-响应头:key-value形式 cookie带在响应头中---》浏览器会把它存到浏览器的cookie中
-响应体:浏览器页面中看到的东西 ---》html标签
# 4 响应状态码
# 5 URL简介 统一资源定位符
统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它
###格式:协议://IP:端口(80)/路径?name=lqz&age=18
http协议,如果不写端口号--》默认是80
?之前的是请求路径,?之后的是请求数据部分
# 补充:
post 既能带在地址栏中数据,又能带在请求体中数据
get请求一般都带在地址栏中
# 补充:
-请求一个网址:
https://www.cnblogs.com/liuqingzheng/articles
域名(https://www.cnblogs.com)+路径(liuqingzheng/articles)
-携带数据到后端:有哪几种方式?
1 带在地址栏中 域名+路径+参数
https://www.cnblogs.com/liuqingzheng/articles?name=xx&age=111
django从:requets.GET request.get_full_path
2 带在请求体中---》http的请求体--》多种编码格式
-json:后期会使用它多
-urlencoded:form表单,默认
-form-data:传文件
django从:request.POST request.body
3 带在请求头中
django中哪里取 request.META--->取出请求头
-服务端响应给客户端数据
-响应头中
-用的最多:响应体
$.ajax({
path:/login/?name=lqz,
data:{}
})----->写成这样---》最终它会变成一个http请求,写的path实际是请求路径,写的data就是请求体
http协议补充
# http 基于tcp的---》可靠传输
#http协议 0.9版本
客户端----》服务端
建立tcp的链接---》三次握手
客户端给服务端发送消息---》借助于tcp通道
服务端给客户端回消息----》借助于tcp通道
断开tcp的链接----》四次挥手
# http 主流 1.1 ---》keep-alive---》时间---》过了时间---》tcp就会断开
客户端同时发送两个http请求
客户端----》服务端
建立tcp的链接---》三次握手
---第一次请求----
客户端给服务端发送消息---》借助于tcp通道
服务端给客户端回消息----》借助于tcp通道
---第二次请求----
客户端给服务端发送消息---》借助于tcp通道
服务端给客户端回消息----》借助于tcp通道
断开tcp的链接----》四次挥手
# http 2.x版本---->多路复用
客户端同时发送5个http请求
客户端----》服务端
建立tcp的链接---》三次握手
tcp是流式协议---》一次带了一些数据 【请求1的数据,请求2的数据,请求3的数据,请求4的数据,请求5的数据 】
tcp的响应---》一次性带回来了
断开tcp的链接----》四次挥手
# http 3.x版本---》使用udp+协议 保证了可靠
web框架
from wsgiref.simple_server import make_server
def mya(environ, start_response):
print(environ)
start_response('200 OK', [('Content-Type', 'text/html')])
if environ.get('PATH_INFO') == '/index':
with open('index.html','rb') as f:
data=f.read()
elif environ.get('PATH_INFO') == '/login':
with open('login.html', 'rb') as f:
data = f.read()
else:
data=b'<h1>Hello, web!</h1>'
return [data]
# 可调用对象---》能加括号执行的对象
if __name__ == '__main__':
myserver = make_server('', 8011, mya) # 请求来了---》经过wsgiref---》调用后面的可调用对象--》传入两个参数(environ, start_response)
print('监听8011')
myserver.serve_forever()
Django
1.MVC与MTV模型 --->所有web框架其实都遵循mvc架构
# MVC 本来坨在一起的代码,拆到不同的位置
模型(M:数据层),控制器(C:逻辑判断)和视图(V:用户看到的)三层
他们之间以一种插件式的、松耦合的方式连接在一起,模型负责业务对象与数据库的映射(ORM),视图负责与用户的交互(页面),控制器接受用户的输入调用模型和视图完成用户的请求
# MTV
M 代表模型(Model): 负责业务对象和数据库的关系映射(ORM)。
M就是原来的M
T 代表模板 (Template):负责如何把页面展示给用户(html)。
T就是原来的V
V 代表视图(View): 负责业务逻辑,并在适当时候调用Model和Template
V+路由 是原来的C
2.下载Django
-命令创建
django-admin startproject 项目名
-使用pycharm创建---》本质也是在执行这个命令,编辑器帮咱们做了
3 django目录结构
4 启动项目
-python manage.py runserver 0.0.0.0:8080
-运行在127.0.0.1和0.0.0.0上的区别
-pycharm中点击绿色箭头运行
5 请求声明周期
路由控制
1 路由是什么
URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码对应执行
请求路径和要执行的视图函数的对应关系
2 如何使用
-path:准确路径,精准匹配---》以后基本都是path
-re_path---》就是原来的url---》正则匹配---》非常少
-放在列表中:urlpatterns = []--->列表中得数据,必须是 path或re_path执行完的结果
3 path详细使用
path('admin/', login)---》
等价于:_path(route, view, kwargs=None, name=None)
第一个参数:
准确路径,字符串
转换器: '<int:pk>' '<str:name>'
-127.0.0.1:8080/login/justin---->path('login/<str:name>', admin.site.urls),
-视图函数中 def login(request,name)
第二个参数: 视图函数的内存地址 不要加括号
-路由一旦匹配成功,就会执行 你写的这个视图函数(request),并且会把request对象传入
-如果有分组的参数[有名,无名],或者转换器的参数,都会被传递到视图函数中作为参数
-总结:放要放视图函数地址---》但是视图函数的参数:第一个是固定必须是request,后续的取决于写没写转换器,写没写有名无名分组
第三个参数:kwargs 是给视图函数传递默认参数
第四个参数:路径的别名---》后期使用反向解析得到该路径
4 re_path的详细使用
跟path除了第一个参数不一样,其他完全一样
第一个参数是:正则表达式
后期用的很少,危险性大---》原来之所以支持正则的目的是为了分组出参数
path通过转换器能完成这个操作--》于是--》这个几乎不用
5 反向解析--->用在视图函数中,用在模板中
-没有转换器的情况:
path('login/', login,name='login')
res=reverse('login') #当时 定义路径传入的name参数对应的字符串
-有转换器的情况:
path('login/<str:name>', login,name='login')
res=reverse('login',kwargs={name:lqz}) #当时 定义路径传入的name参数对应的字符串
生成这种路径:'login/lqz'
6 路由分发
-为什么默认路由匹配就匹配到了 urls.py ?
-settings.py 有配置的
-ROOT_URLCONF = 'django_demo02.urls'
-一个app自己有自己的路由
-在app下创建urls.py
视图层
1 views.py 这个文件---》目前写的是视图函数
2 视图函数必须写成这样
def 视图函数(request):
return 四件套
4 四件套
-它是http请求(数据包---》字符串形式)---》拆分成了django中得request对象
-常用的:
request.path
request.method
request.GET
requets.POST
requets.body
request.get_full_path() # 方法
request.files # 前端携带文件过来---》转成了字典,根据文件的名字取到文件对象
-不常用
request.cookie
request.session
request.content_type # 提交的编码格式:urlencoded(form表单),json,form-data,text/plain(一般不用,浏览器默认的格式)
request.META: 请求头中得数据
user-agent:HTTP_USER_AGENT
referer:
客户端ip地址:REMOTE_ADDR
用户自定义的
定义:name=lqz
取:request.META.get('HTTP_NAME') # 前面加HTTP_ 把自定义的转成大写
-request.user # auth
-request.is_ajax()
5 cbv
6 文件上传
作业
mysql分组
以表头为依据对数据分组
select * from 表名 group by 表头;
设置sql_mode为only_full_group_by(严格模式:未设置时会呈现每一个分组的第一条数据整条。设置严格模式之后只会呈现表头数据)
set global sql_mode="strict_trans_tables,only_full_group_by"
配合聚合函数 max min sum avg count使用
select post as '部门',max(salary) as '最高工资' from emp group by post;
concat_ws() (显示想提取的数据,用 ' | ' )分割
select post,concat_ws('|', name, age, gender) from emp group by post;
get请求能携带请求体吗?
可以携带,但是不推荐,也没有人用,很多浏览器的lib文件也没有配置get‘的请求体
环境变量有什么用
指定目标文件的路径,可以在操作系统中直接使用,加强路径控制,减少路径冲突
0.0.0.0和localhost和127.0.0.1有什么区别
1.127.0.0.1是一个回环地址,也称为环回接口地址或loopback地址。它是用于本地机器内部通信的特殊IP地址。当应用程序尝试访问这个地址时,数据将不会离开本地机器,而是通过内核处理后直接返回。它通常被用于测试和开发目的,用于在本机上模拟网络通信。
2.localhost是一个主机名,通常映射到回环地址127.0.0.1。它是用于在本地机器上访问自己的网络服务的常用方式。当你在浏览器中输入localhost时,实际上是在请求回环地址。
3.0.0.0.0是一个特殊的IP地址,被用作通配符地址或未指定地址。当一个网络服务监听0.0.0.0时,它将接受来自任意IP地址的连接。这样可以使服务在所有可用的网络接口上监听,而不仅仅是一个特定的IP地址。在某些情况下,0.0.0.0也可以表示"任何地址"。
总结:127.0.0.1是一个特殊的回环地址,用于本地机器内部通信;localhost是一个映射到回环地址的主机名,用于在本地访问自己的网络服务;0.0.0.0是一个通配符地址,用于服务监听所有可用的网络接口。
7 写个django项目---》中间件---》取出用户访问的 user-agent和ip地址,(sqlite,mysql)建个表,存到表汇总
models
views
开放端口
8 使用echars,画出饼形图展示客户端类型的比例
读取数据库数据
分组
count出信息总数
将数据返回前段/后端
from django.shortcuts import render, HttpResponse
from app01 import models
from django.db.models import Count
def index(request):
ip = request.META.get('REMOTE_ADDR')
ug = request.META.get('HTTP_USER_AGENT')
models.info.objects.create(ip=ip,user_agent=ug)
obj = models.info.objects.values('ip').annotate(count=Count('ip'))
obj1 = []
obj2 = []
for i in obj:
obj1.append(i['ip'])
obj2.append(int(i['count']))
return render(request,'index.html',locals())
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../static/echarts.js"></script>
</head>
<body>
<div id="main" style="width: 1000px;height: 800px;"></div>
<script type="text/javascript">
var obj1={{ obj1|safe }}
var obj2={{ obj2|safe }}
var myChart = echarts.init(document.getElementById('main'));
var option = {
title: {
text: '访问次数'
},
tooltip: {},
legend: {
data: ['']
},
xAxis: {
data: obj1
},
yAxis: {},
series: [
{
name: '访问次数',
type: 'bar',
data: obj2
}
]
};
myChart.setOption(option);
</script>
</body>
</html>