今日内容大纲:
1.起飞版web框架
2.自定制框架的流程
3.jinja2模板渲染初识
4.MVC&&MTV
5.django版本介绍及django安装
6.django初识(一些操作)
今日详细内容:
1.起飞版web框架
2.自定制框架的流程
1.浏览器发送请求(http://127.0.0.1:8080/index)
2.=(请求)=>wsgiref的参数environ
==>environ拿到请求路径(根据不同的路径返回不同的页面),返回页面通过函数里的文件读取页面内容,把文件进行返回
==>主逻辑里面写了通过路径找到对应函数的逻辑,urls.py里面写的那个列表,列表的元素是一个个元组,每个元组的第一个元素就是路径,第二个元素就是对应的函数名字,主逻辑代码连通过路径找到对应的函数去执行
3.==>views.py函数,读取页面html文件,返回给浏览器,返回给浏览器这个操作是主逻辑做的
==>主逻辑通过wsgiref中的start_response,把响应头的信息发送一下,return也就返回页面数据
==>主逻辑通过for..else等操作,进行返回不同页面的数据,最后传输给了浏览器
4.==>浏览器拿到了login页面,输入用户名和密码,
5.==>同样需要发送请求给服务端,也就是提交自己输入的密码和用户名(提交请求)
6.==>服务器端wsgiref把很多信息封装在environ对象中,environ中有用户名和密码
也就是通过environ这个变量找到用户的数据,
7.==>主逻辑连接数据库,查找是都存在对应的用户信息数据(有则登录成功,没有,则登录失败)
(在第7步之前做出来就行了,功能就是创建表,插入数据)
##数据库部分
==>models.py,通过sql创建了用户表&&用户信息
==>数据库里边有数据了
3.jinja2模板渲染初识
介绍:
django里面并没有用jinja2,为什么要讲它呢,因为django的模板语言,也就是做字符串替换的功能和jinja2的语法很像,所有学完django之后,再学flask就很容易了。
上面的代码实现了一个简单的动态,我完全可以从数据库中查询数据,然后去替换我html中的对应内容,然后再发送给浏览器完成渲染。 这个过程就相当于HTML模板渲染数据。 本质上就是HTML内容中利用一些特殊的符号来替换要展示的数据。 我这里用的特殊符号是我定义的,其实模板渲染有个现成的工具: jinja2
下载jinja2 (:flask框架一般使用这个模板语言。)
jinja2的下载安装方式:
pip install jinja2
动态页面的效果:
# Author: studybrother sun
from threading import Thread
import socket
server=socket.socket()
server.bind(('127.0.0.1',8080))
server.listen()
#返回不同页面写的按个首页homepage函数
# def homepage(conn):
# with open('homepage.html','rb') as f:
# data=f.read()
# #注意,这里读取的是服务端的数据
# conn.send(data)
# #这里指的是,发现客户端
import datetime
def homepage(conn):
with open('homepage.html','r',encoding='utf-8') as f:
data=f.read()
# 注意,这里读取的是服务端的数据
t1=datetime.datetime.now()
new_data=data.replace('@xx@',str(t1))
#注意这里的date,必须有数据接收才行
conn.send(new_data.encode('utf-8'))
#这里指的是,发现客户端
#动态效果,也是在这里操作服务端的页面,进行字符串的替换实现的,在这个地方
# def index(conn):
# with open('index.html','rb') as f:
# data=f.read()
# #注意,这里读取的是服务端的数据
# conn.send(data)
#
# def home(conn):
# with open('home.html','rb') as f:
# data=f.read()
# #注意,这里读取的是服务端的数据
# conn.send(data)
#下面是运用反射的写法
urlpatterns=[
('/',homepage),
# ('/index',index),
# ('/home',home),
# 同理,只需要在这里修改就可以了,拿到页面
]
# 我们需要做的事情是:写函数,配置对应关系
while 1:
conn,addr=server.accept()
# 拿到conn就开始并发,开进程,线程池和进程池!!!!!!
from_b_msg=conn.recv(1024).decode('utf-8')
# print(from_b_msg)
path=from_b_msg.split('\r\n')[0].split(" ")[1]
# print(path)
# conn.send(b'HTTP/1.1 200 ok\r\n\r\n')
conn.send(b'HTTP/1.1 200 ok\r\nk1:v1\r\n\r\n')
# 在这里可以加上响应的头部信息
# conn.send(b'<h1>hello</h1>')
for url_func in urlpatterns:
if url_func[0]==path:
#多线程函数版
t=Thread(target=url_func[1],args=(conn,))
t.start()
# 简单函数版
# url_func[1](conn)
test.py
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-Type" charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width" ,initial-scale="1">
<!--上边这个表示手机版的调整尺寸-->
<!--上述2个meta标签"必须"放在最前面,任何其他内容都必须跟随其后-->
<title>Title</title>
</head>
<body>
<h1 style="color: red">欢迎来到首页</h1>
<a href="http://127.0.0.1:8080/index">主页链接到index页面</a>
<a href="http://127.0.0.1:8080/home">主页链接到home页面</a>
<!--服务端不用断,在浏览器端访问直接就可以拿到了html-->
<h1 style="color: deeppink;">@xx@</h1>
</body>
</html>
homepage.html
jinja2练习:(注意原生socket和wsgiref的区别)
# Author: studybrother sun
from threading import Thread
import socket
from jinja2 import Template
# 导入jinja2模板库
import datetime
server=socket.socket()
server.bind(('127.0.0.1',8080))
server.listen()
#返回不同页面写的按个首页homepage函数
# def homepage(conn):
# with open('homepage.html','rb') as f:
# data=f.read()
# #注意,这里读取的是服务端的数据
# conn.send(data)
# #这里指的是,发现客户端
def homepage(conn):
with open('jinja2page.html','r',encoding='utf-8')as f:
data=f.read()
t=Template(data)
#模板渲染语言
new_data=t.render({"name": "Alex", "hobby_list": ["烫头", "泡吧"]})
#这个地方需要通过send发送的,因为没有用wsgiref模块,用的是原生的socket
#socket用 send
conn.send(new_data.encode('utf-8'))
#wsgiref用return
# return [bytes(new_data, encoding="utf8"), ]
# return [new_data.encode('utf-8'),]
# with open('homepage.html','r',encoding='utf-8') as f:
# data=f.read()
# # 注意,这里读取的是服务端的数据
# t1=datetime.datetime.now()
# new_data=data.replace('@xx@',str(t1))
# #注意这里的date,必须有数据接收才行
# conn.send(new_data.encode('utf-8'))
#这里指的是,发现客户端
#动态效果,也是在这里操作服务端的页面,进行字符串的替换实现的,在这个地方
# def index(conn):
# with open('index.html','rb') as f:
# data=f.read()
# #注意,这里读取的是服务端的数据
# conn.send(data)
#
# def home(conn):
# with open('home.html','rb') as f:
# data=f.read()
# #注意,这里读取的是服务端的数据
# conn.send(data)
#下面是运用反射的写法
urlpatterns=[
('/',homepage),
# ('/index',index),
# ('/home',home),
# 同理,只需要在这里修改就可以了,拿到页面
]
# 我们需要做的事情是:写函数,配置对应关系
while 1:
conn,addr=server.accept()
# 拿到conn就开始并发,开进程,线程池和进程池!!!!!!
from_b_msg=conn.recv(1024).decode('utf-8')
# print(from_b_msg)
path=from_b_msg.split('\r\n')[0].split(" ")[1]
# print(path)
# conn.send(b'HTTP/1.1 200 ok\r\n\r\n')
conn.send(b'HTTP/1.1 200 ok\r\nk1:v1\r\n\r\n')
# 在这里可以加上响应的头部信息
# conn.send(b'<h1>hello</h1>')
for url_func in urlpatterns:
if url_func[0]==path:
#多线程函数版
t=Thread(target=url_func[1],args=(conn,))
t.start()
# 简单函数版
# url_func[1](conn)
jinja2_test.py
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-Type" charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width" ,initial-scale="1">
<!--上边这个表示手机版的调整尺寸-->
<!--上述2个meta标签"必须"放在最前面,任何其他内容都必须跟随其后-->
<title>Title</title>
</head>
<body>
<h1>姓名:{{ name }}</h1>
<ul>
{% for hobby in hobby_list%}
<li>{{ hobby }}</li>
{% endfor %}
</ul>
</body>
</html>
jinja2page.html
练习:jinja2的变量&&for循环
4.MVC&&MTV
MVC&&MTV框架
MVC
M:model.py 就是和数据库打交道用的,创建表等操作
V:view 视图(视图函数,html文件)
C:controller控制器(其实就是找百度云diamante里面那个urls文件里面的内容),
url(路径)分发与视图函数的逻辑处理
MTV:django中的处理框架
M:model.py 就是和数据库打交道用的,创建表等操作(同上)
T: templates存放html文件的
V:view 视图函数(进行逻辑处理)
总结:对比上边,我们会发现MTV少一个url分发的部分
所以学习django,我们还要学一个叫做url控制器(路径分发)的东西,MTV+url控制器就是我们django要学的内容
也就是:MTVU框架
5.django版本介绍及django安装
(1)django版本支持的官网图解&&菜鸟图解
图解1:
图解2:
菜鸟教程django版本图解3:
(2)django安装
django官网&&下载页面
A:下载django:
pip install django==1.11.11
B:创建一个django project命令
django-admin startproject mysite 创建一个名字为"mysite"的django项目
安装安成之后是这个目录,将这个目录配置环境变量,通过django-admin就能创建django项目,并且django项目应用的就是你python36的python解释器
django-admin命令获取的一些操作命令(图解):
(3)测试我们的第一个django项目(切换目录&&创建mysite2):
创建之后的目录结构:
当前目录会生成mysite的工程,目录结构如下(下面的mysite改成mysite2,)
注意:pip下载下来的django可以理解成一个模块,而不是django项目,这个模块可以帮助我们创建django项目.
manage.py:django项目里面的工具,通过他可以调用django shell和数据库,启动关闭项目与项目交互等,不管你将框架分了几个文件,必然有一个启动文件,其实他们本身就是一个文件.
__init__.py:表示mysite是一个包,别人可以引入你.
settings.py:包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作变量.
urls.py:负责把URL模式映射到应用程序
wsgi.py:runserver命令就使用wsgiref模块做简单的web server,后面会看到runserver,所有与socket相关的内容都在这个文件里面.
切换到创建好的项目,运行如下:
运行结果:
(注意在浏览器中输入:127.0.0.1:8080),显示如下结果
此时已经开始启动django项目了,只不过什么逻辑都没有
(4)应用&&项目
你会发现,上面没有什么view视图函数的文件,这里我们说一个应用与项目的关系,上面我们只是创建了一个项目,并没有创建应用.以微信来举例,微信是不是一个大的项目,但是微信里面是不是有很多个应用,支付应用、聊天应用、朋友圈、小程序等这些在一定程度上都是相互独立的应用,也就是说一个大的项目里面可以有多个应用,也就是说项目是包含应用的,它没有将view放到这个项目目录里面是因为它觉得,一个项目里面可以有多个应用,而每个应用都有自己这个应用的逻辑内容,所以他觉得这个view应该放到应用里面,比如说我们的微信,刚才说了几个应用,这几个应用的逻辑能放到一起吗,放到一起是不是就乱套啦,也不好管理和维护,所以这些应用的逻辑都分开来放,它就帮我们提炼出来了,提炼出来一个叫做应用的东西,所以我们需要来创建这个应用。
A:创建应用的命令:
python manage.py startapp blog #通过执行manage.py文件来创建应用,执行这句话一定要注意,你应该在这个manage.py的文件所在目录下执行这句话,因为其他目录里面没有这个文件
python manage.py startapp blog2 #每个应用都有自己的目录,每个应用的目录下都有自己的views.py视图函数和models.py数据库操作相关的文件
B:目录截图:
C:我们重点看两个文件
models.py:之前我们写的那个名为model的文件就是创建表用的,这个文件就是存放与该app(应用)相关的表结构的.
views.py:存放于该app相关的视图函数的
(5)启动django项目
几种在DOS命令窗中启动django的方法:
python manage.py runserver
python manage.py runserver 8080
python manage.py runserver 127.0.0.1:8080 #本机测试就不写ip地址了,但是连端口都没写,默认是本机的8000端口
6.django初识(一些操作)
学习django,我们就学上边的这些文件,怎么在MTV+url分发的功能下来使用.
以后我们创建django项目,很少用命令行了,就用pycharm来创建.
(1)pycharm创建django项目
步骤1:(File==>New Project)
步骤2:
步骤3:点击Create
目录结果:
步骤4:
点击,绿色的三角形,运行.
由于电脑的配置关系,可能又要稍长一点的时间.
运行起来之后,输出窗,输出结果如下,证明运行起来了
步骤5:(在浏览器中输入:127.0.0.1:8000),输出结果如下
(2)一些配置介绍
A: django通过以下,进行路径配置,查找路径的.下面这个在settings.py界面
B: django的基础路径,以下界面也是在,settings中.
首先找到,settings的绝对路径,在找父路径,再找父路径.
这样把项目拷贝走,在哪里都能运行.
C: urls文件中的信息.
(3)一个简单的小项目,简单配置
A:首先,找路径页面,进行路径分发,urls.py页面中进行如下操作:
url(r'^login/', views.login),
鼠标左键+urls界面的views==>views页面.
views.py中写如下内容,
在后边加上HttpResponse,进行服务端的响应,添加的语句如下.
from django.shortcuts import render,HttpResponse
# Create your views here.
def login(request):
#request是请求的意思,调用url的时候传输的
return HttpResponse('这是登录页面')
C:运行,输入网址(127.0.0.1:8000/login/),运行结果如下.
(4)django的一个登录界面:
A:对(3)进行修改,login.html页面方法到templates中,
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="content-Type" charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width" ,initial-scale="1">
<!--上边这个表示手机版的调整尺寸-->
<!--上述2个meta标签"必须"放在最前面,任何其他内容都必须跟随其后-->
<title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8080/auth" method="get">
<!--在这里的action的目的是,提交之后跳转的路径是auth界面-->
<!--请求方式改写成,也就是提交之后的方法用get方法-->
<label for="username">用户名</label><input id="username" type="text" name="username">
<label for="password">密码</label><input id="password" type="password" name="password">
<!--type设置成password的目的是将密码隐藏起来-->
<!--这里的name=username,这个键值对写的原因是,在浏览器上的搜索框显示-->
<input type="submit">
</form>
</body>
</html>
B:在view.py文件中修改如下:
C:访问下列地址(127.0.0.1:8000/login/),运行结果如下:
<form action="http://127.0.0.1:8080/auth" method="get">
form表单表示,在当前访问页面&&提交数据
(5)在(4)的基础上,思考form表单,向哪提交消息
(是否可以写两个页面,一个访问页面,一个提交数据)
A:在login.html中修改form表单,
<form action="" method="post">
B:在views.py页面中进行判断一下,进行处理,提交数据用post方法,访问页面用get方法.
C:运行项目,结果如下,
D.在服务端收到信息,如下截图:在服务端收到get请求
E:在浏览器中随便输入用户:donggua,密码:123,点击"提交".结果如下图:
forbidden,这些东西是django对其进行的一些配置.
F:把settings.py的
'django.middleware.csrf.CsrfViewMiddleware',注销掉
这个注销掉的是中间件,后面会讲到
G:再次在浏览器中输入(http://127.0.0.1:8000/login/),输入用户:donggua,密码:123,然后点击提交.
原因是:form表单的action,也就是提交地址为空,也就是当前页面路径下提交数据.
<form action="" method="post">
结果:
H:然后走urls.py,找到对应的函数,
然后,找到对应的请求方法,也就是在views.py中找到
打印的请求结果就是post了,如下图:
I.在下图中,我们可以通过得到的是GET还是POST进行判断,是请求页面,还是提交数据
if条件判断,如果是GET,则返回页面,如果是POST,提交数据,如何获取数据???
目前request封装的是个对象,wsgiref封装的是个字典,request.method进行调用其内部的方法,字典通过中括号,索引进行取值.app请求的request对象
J.views对应的代码.
K.运行,随便提交,密码和用户
结果如下:
L.如果没有返回值,views.py代码如下:
运行之后,在浏览器中输入(http://127.0.0.1:8000/login/),输入密码和用户,得到的结果如下:
因此,在写的时候必须return一个东西.
地址:127.0.0.1:8000/login,提交之后,会在地址之后加上一个/
(6)
A:修改代码如下,
B:输入网址:127.0.0.1:8000/login/ ,输入用户名:alex,密码123
得到的结果是:
C:服务端得到的结果:用户名和密码
(7)
A:修改代码如下,
B:在浏览器中输入地址,(127.0.0.1:8000/login/)
用户名输入错误,结果
输入正确,结果:
(8)post和get获取数据
获取用户的请求方法:
(9)一些备注和,上边的整体代码.
from django.shortcuts import render,HttpResponse
# Create your views here.
def login(request):
#获取用户的请求方法
method=request.method
if method=='GET':
#返回页面
return render(request,'login.html')
else:
#post方法获取数据,都是字符串类型
uname=request.POST.get('username')
# get方法获取数据
# uname = request.GET.get('username')
pwd=request.POST.get('password')
print(uname,pwd)
if uname=='sb'and pwd=='222':
#返回消息,写字符串就行
return HttpResponse('登录成功')
else:
return HttpResponse('验证失败')
# return render(request,'login.html')
#request是请求的意思,调用url的时候传输的
(10)
A:修改成get请求方式
html中修改成这个get
<form action="" method="get">
views.py文件改成下面的格式
B:运行,在浏览器中,输入下面的网址:
服务端收到的结果:
(11)
A:在(10)的基础上,进一步,修改如下截图:
B.修改views.py文件.
在这里,我们走home,就返回login页面.
C.此时运行(127.0.0.1:8000/home/),输入用户名和密码,得到如下内容.
服务端,没有收到任何信息.
D:分析:login.html这个时候,需要改写表单.
<form action="http://127.0.0.1:8000/login/" method="get">
E.刷新页面,得到的结果如下:
F:输入:用户名sb,密码:222
提交之后,得到的页面如下:
服务端得到如下信息:
(12)动态页面
A.操作urls
B.在views.py页面中添加
上边最后一行是,模板渲染
C.在templates页面中,添加index.html页面.(进行时间替换)
运行结果如下:(每次实践都会发生变化)
(13)端口修改
A:
B:
预习内容:
django认识,按照下面的步骤学习:
1.django的url控制器
2.django的视图
3.django的模板(templates)
4.ORM(花的时间比较久)