巨蟒python全栈开发django2:初识django
今日内容大纲:
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)
<!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>
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)
<!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>
练习: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安装
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的文件所在目录下执行这句话,因为其他目录里面没有这个文件
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页面中进行如下操作:
from app01 import views
url(r'^login/', views.login),
鼠标左键+urls界面的views==>views页面.
B:在界面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(花的时间比较久)