web框架---django
Posted 西西
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了web框架---django相关的知识,希望对你有一定的参考价值。
15:31:14一.web框架
1.框架:即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演。对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。
2.Web应用:就是先把html用文件保存好,用一个现成的HTTP服务器软件(apache/nginx),接收用户请求,从文件中读取HTML,返回。做法是底层代码由专门的服务器软件实现,我们用Python专注于生成HTML文档。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口,让我们专心用Python编写Web业务。
3.接口:是WSGI(Web服务器网关接口协议):Web Server Gateway Interface。
二.MVC和MTV模式
1.MVC模式:MVC就是把web应用分为模型(M),控制器(Controller),视图(V)三层;他们之间以一种插件似的,松耦合的方式连接在一起。
(1)模型(Model):模型负责业务对象与数据库的对象(ORM)
(2)页面(View):负责与用户的交互(页面),一个个html的文件
(3)控制器(Controller):接受用户的输入调用模型和视图完成用户的请求。
2.MTV模式(Django):本质上与MVC模式没有什么差别,也是各组件之间为了保持松耦合关系,只是定义上有些许不同代表:
(1)Model(模型):负责业务对象与数据库的对象(ORM)
(2)Template(模版):负责如何把页面展示给用户,一个个html的文件
(3)View(视图):负责业务逻辑,并在适当的时候调用Model和Template
(4)Django有一个url(控制器):它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template
3.MTV模式访问流程:
用户输入URL--->根据URL匹配相应视图函数view.py,视图函数view.py可以去models数据库里取数据把要展示的东西返回成Template模版(HTML)给用户看,也可以直接把要展示东西返回成Template模版(HTML)给用户看
4.django的请求生命周期是什么
当用户在浏览器上点url之后在django后台都发生了什么。
第一步:客户端首先把请求(字符串包括请求头和请求体)建立起来发给服务器端
第二步:服务端根据发来的url来定位该做什么,如果传来的数据如果是GET方式传来数据只放在url上用reqeust.GET从请求头里取,请求体里是空的。如果是POST方式传来的就用reqeust.post方式从请求体里取,请求头url里也可以有数据。请求体默认是reqeust.body(原生字符串内容),django在内部把reqeust.body转换成requst.post(字典)。到达路由映射urls.py。
第三步:路由映射里进行匹配(从上到下匹配,如果第一个成功了就不进行匹配),匹配成功触发函数views.py,匹配不成功报错404。有俩种对应方式:1.一个URL对应一个函数这种模式叫FBV模式(视图views里用函数处理用户逻辑请求)。2.一个URL对应一个类这种模式叫CBV模式。如果是类模式在django里执行一个dispatch方法,dispatch方法再根据method通过反射执行GET或POST方法。
第四步:业务处理-根据个人需求自定比如操作数据库(原生SQL,Django ORM),产生结果返回给用户
第五步:返回给用户结果响应内容,包含响应头和响应体
三.django的流程和命令行工具
1.django项目实现流程
(1)安装django
命令:pip3 install django
(2)创建django项目
语法:django-admin startproject 项目名称
创建语句:django-admin startproject mysite
mysite项目目录里包括
---mysite(全局内容)
---settings.py(django相关的所有配置信息)
---url.py(路径分发)
---wsgi.py(协议)
---- manage.py(启动文件)
(3)创建一个应用
在项目目录mysite里创建应用
语法:python manage.py startapp 应用名称
创建语句:python manage.py startapp blog
blog应用目录里包括
---blog(blog应用)
---__init__.py
---admin.py(django后台管理系统)
---apps.py
---models.py(数据库相关-ORM框架内容)
---tests.py(测试用)
---views.py(视图,放函数)
---migrations
---__int__.py
(4)启动django项目:
命令:python manage.py runserver 8080
2.通过django实现一个简单静态应用
当输入http://127.0.0.1:8080/show_time/返回当前为红色字体的时间
(1)在mysite项目目录下blog应用里创建static目录(放静态文件jquery-3.1.1.js)
(2)在全局配置文件里mysite/settings.py配置:
INSTALLED_APPS = [ #所有应用的名称 \'django.contrib.admin\', \'django.contrib.auth\', \'django.contrib.contenttypes\', \'django.contrib.sessions\', \'django.contrib.messages\', \'django.contrib.staticfiles\', "blog", #添加blog应用名称 ]
#让django能找到static目录的绝对路径取个别名叫static,用这个代替下面的这个 STATIC_URL = \'/static/\' #设定django能找到static目录的绝对路径 STATICFILES_DIRS=( os.path.join(BASE_DIR,"blog/static"),)
(3)静态文件交由Web服务器处理,Django本身不处理静态文件。简单的处理逻辑如下(以nginx为例):
URI请求----->按照Web服务器里面的配置规则先处理,以nginx为例,主要请求配置在nginx.conf里的location
----->如果是静态文件,则由nginx直接处理
----->如果不是则交由Django处理,Django根据urls.py里面的规则进行匹配
全局url(控制器)配置:mysite\\urls.py
from django.conf.urls import url from django.contrib import admin from blog import views #导入blog应用下的views urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r\'^show_time/\',views.show_time) #对应视图函数views.show_time处理/show_time这个路径 ]
(4)views视图函数配置:mysite\\blog\\views.py
from django.shortcuts import render,HttpResponse #引入HttpResponse对象(服务器把这个对象通过HTTP协议把它发给浏览器) import time def show_time(requset): #requset形参:浏览器发送给服务器,之后服务器打包成的信息对象 #return HttpResponse(\'hello\') #HttpResponse字符串对象是打包发给服务器,让服务器发给前端 t=time.ctime() #获取当前时间赋值给t return render(requset,"index.html",{"time":t}) #render方法参数1:请求对象requset,参数2:返回的页面,参数3:把对象t时间点和"time"字符串组成键值对发送给前端
(5)index.html页面配置:mysite\\templates\\index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> {% load staticfiles %} <!--模版引入jquery-3.1.1.js用--> <title>时间</title> </head> <body> <h1>{{ time }}</h1> <!--通过俩个{{}}把time渲染出来--> <!--引入jquery-3.1.1.js方式1--> <!--<script src="/static/jquery-3.1.1.js"></script> --> <!--引入jquery-3.1.1.js方式2--> <script src="{% static \'jquery-3.1.1.js\' %}"></script> <script> $("h1").css("color","red") </script> </body> </html>
访问:http://127.0.0.1:8080/show_time/
返回:Mon Dec 17 15:38:16 2018
四.django的url路由系统
1.URL配置(URLconf)
就像Django所支撑网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。
FBV模式语法:一个URL对应一个函数这种模式
urlpatterns = [
url(正则表达式, views视图函数,参数,别名),
]
(1)正则表达式
方式一:无命名分组(后端的形参可以随便写)
全局url(控制器)配置:mysite\\urls.py
from django.conf.urls import url from django.contrib import admin from blog import views urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r\'^article/(\\d{4})/(\\d{2})\',views.article_year), #(\\d{4})年份分组和(\\d{2})月份分组的内容就是视图函数里的参数 ]
views视图函数配置:mysite\\blog\\views.py
from django.shortcuts import render,HttpResponse import time def article_year(request,year,month): #接收urls.py里传的参数request,year接收分组的年份,month接收分组的月份 return HttpResponse("年份:%s 月份:%s" %(year,month)) #
访问:http://127.0.0.1:8080/article/2018/12
显示:年份:2018 月份:12
正则表达式方式二:有名分组
全局url(控制器)配置:mysite\\urls.py
from django.conf.urls import url from django.contrib import admin from blog import views urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r\'^article/(?P<year>\\d{4})/(?P<month>\\d{2})\',views.article_year), #有名(?P<year>\\d{4})分组和有有名分组(?P<month>)的内容就是视图函数里的参数
views视图函数配置:mysite\\blog\\views.py
from django.shortcuts import render,HttpResponse
import time
def article_year(request,year,month): #接收urls.py里传的参数request,命名的year接收分组的年份,命名的month接收分组的月份
return HttpResponse("年份:%s 月份:%s" %(year,month)) #
访问:http://127.0.0.1:8080/article/2018/12
显示:年份:2018 月份:12
(2)别名
<1>全局url(控制器)配置:mysite\\urls.py
from django.conf.urls import url from django.contrib import admin from blog import views urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r"register",views.register,name="reg"), #别名=reg ]
<2>views视图函数配置:mysite\\blog\\views.py
from django.shortcuts import render,HttpResponse import time def register(request): #第一步:第一次通过URL进来GET请求进入到视图函数 #第三步:当用户输入信息通过form表单提交后第二次进来POST请求 if request.method == "POST": #第四步:如果post请求走这里 print(request.POST.get("user")) print(request.POST.get("age")) return HttpResponse("success!") #第五步:返回success return render(request,"register.html") #第二步:如果GET方式请求render访问register.html注册页面
<3>register.html页面配置
<!DOCTYPE html> <html lang="en"> <head> {% load staticfiles %} <meta charset="UTF-8"> <title>注册表单</title> </head> <body> <h1>学生注册</h1> <hr> <form action="{% url \'reg\' %}" method="post"> <!--提交后注册到action=reg(别名),通过post方式发送--> <p>姓名<input type="text" name="user"></p> <p>年龄<input type="text" name="age"></p> <p><input type="submit"></p> </form> </body> </html>
访问:http://127.0.0.1:8080/register输入好用户名xixi和年龄18后
页面返回:success!
服务端返回:
xixi
18
(3)URL路由分发
分发单独bolg项目
<1>全局配置/mysite/urls.py做分发
from django.conf.urls import url,include #引入include做分发 from django.contrib import admin from blog import views urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r\'^blog/\', include(\'blog.urls\')), #只要是开头以blog开头的都分发到blog.urls下面去找 ]
<2>项目局部配置/mysite/blog/urls.py
from django.conf.urls import url,include #引入include做分发 from django.contrib import admin from blog import views urlpatterns = [ url(r\'article/(\\d{4})/(\\d{2})\',views.article_year), #(\\d{4})分组和(\\d{2})分组的内容就是视图函数里的参数 ]
<3>views视图函数配置:mysite\\blog\\views.py
from django.shortcuts import render,HttpResponse import time def article_year(request,year,month): #接收urls.py里传的参数request,year,month return HttpResponse("年份:%s 月份:%s" %(year,month)) #
访问:http://127.0.0.1:8080/blog/article/2018/12
返回:年份:2018 月份:12
(4)CBV模式:一个URL对应一个类这种模式
全局url配置xixi\\xixi\\urls.py
from django.conf.urls import url from django.contrib import admin from app1 import views urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r\'^cbv/\' ,views.CBV.as_view()), #类方式 ]
视图函数xixi\\app1\\views.py配置
from django.shortcuts import render,HttpResponse from app1.models import * from django.views import View class CBV(View): #继承django的View类 def get(self,request): #get方法 return render(request,\'index.html\') #return HttpResponse(\'CBV.GET\') def post(self,request): #post方法 return HttpResponse(\'CBV.POST\')
页面配置:xixi\\app1\\templates\\index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <form action="/cbv/" method="post"> <input type="text" /> <p><input type="submit"></p> </form> </body> </html>
访问:http://127.0.0.1:8080/cbv/
提交查询后返回:CBV.POST
五.Dango Views(视图函数)-- 处理逻辑代码
1.http请求中产生两个核心对象是HttpRequest请求对象和HttpResponse响应对象它们的所在位置在django.http
(1)http请求HttpRequest的属性和方法:
<1>属性包括
path:请求页面的全路径,不包括域名
method:请求中使用的HTTP方法的字符串表示。全大写表示。例如
if req.method=="GET":
do_something()
elseif req.method=="POST":
do_something_else()
GET:包含所有HTTP GET参数的类字典对象
POST:包含所有HTTP POST参数的类字典对象
服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过HTTP POST方法提交请求,但是表单中可能没有数据,因此不能使用if req.POST来判断是否使用了HTTP POST 方法;应该使用if req.method=="POST"
FILES:包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file" name="" />标签中name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:
filename:上传文件名,用字符串表示
content_type:上传文件的Content Type
content:上传文件的原始内容
user:是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你可以通过user的is_authenticated()方法来辨别用户是否登陆:if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware时该属性才可用
<2>方法包括
get_full_path():比如:http://127.0.0.1:8000/index33/?name=123 ,req.get_full_path()得到的结果就是/index33/?name=123
req.path:/index33
(2)http响应HttpResponse对象
对于HttpRequest对象来说,是由django自动创建的,但是,HttpResponse对象就必须我们自己创建。每个view请求处理方法必须返回一个HttpResponse对象。HttpResponse类在django.http.HttpResponse
2.在HttpResponse对象上扩展的常用返回方式(都是请求与响应的过程):
<1>返回字符串:HttpResponse("内容")
<2>页面渲染:render(request,\'index.html\',locals()) #打开index.html读取内容,含有特殊标记用locals()可以直接将函数中所有的变量传给模板替换(渲染),得到新的字符串,返回给用户
<3>页面跳转:redirect("url路径") #加了redirect这个响应到浏览器之后,会告诉其它该跳到那个url路径
3.结合HttpRequest请求对象和HttpResponse响应对象举例:
<1>注册页面:mysite/blog/templates/register.html
<!DOCTYPE html> <html lang="en"> <head> {% load staticfiles %} <meta charset="UTF-8"> <title>注册</title> </head> <body> <h1>注册</h1> <hr> <form action="{% url \'reg\' %}" method="post"> <!--使用别名\'reg\'--> <p>姓名<input type="text" name="user"></p> <p>年龄<input type="text" name="age"></p> <p><input type="submit"></p> </form> </body> </html>
<2>登录页面:mysite/blog/templates/login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="jquery-3.1.1.js"></script> <title>Title</title> </head> <body> <h1>{{ name }} 登录</h1> <!--登陆后用户名--> </body> </html>
<3>全局url(控制器)配置:mysite\\urls.py
from django.conf.urls import url from django.contrib import admin from blog import views urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r"register", views.register,name="reg"), #注册首页 url(r\'^login\', views.login), #登录 ]
views视图函数配置:mysite\\blog\\views.py
from django.shortcuts import render,HttpResponse,redirect import time #注册函数 def register(request): #第一步:第一次进来GET请求 #第三步:当用户输入玩信息提交后第二次进来POST请求 print(request.path) #HttpRequest对象请求属性path请求页面的全路径,不包括域名 print(request.get_full_path()) #HttpRequest对象请求属性get_full_path()带着数据的全路径 #HttpRequest对象请求属性method请求中使用的HTTP方法的字符串表示 if request.method == "POST": #第四步:如果post请求走这里 print(request.POST.get("user")) print(request.POST.get("age")) user=request.POST.get("user") #接收输入的用户 if user=="xixi": #如果输入的用户是xixi return redirect("login/") #通过HttpResponse对象里的redirect方法跳转到urls.py里的login return HttpResponse("注册失败!") #HttpResponse对象的render方法做页面渲染 return render(request,"register.html") #第二步:如果GET请求render访问register.html页面 #登录函数 def login(req): name="xixi" #模拟从数据库把用户名取出来赋值到这里 #HttpResponse对象的render方法把内容渲染到login.html模版里面去 return render(req,"login.html",locals()) #HttpResponse对象上的locals()方法可以直接将函数中的变量name="xixi"传给模板login.html
访问:http://127.0.0.1:8080/register
当注册输入xixi后跳转到登录页面http://127.0.0.1:8080/login/并返回:
xixi 登录
4.Session与Cookie(键值对)
(1)cookie:不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生。
(2)cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地客户端浏览器上某个文件里面的键值对;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁”了。
(3)session:cookie虽然在一定程度上解决了“保持状态”的需求,但是由于cookie本身最大支持4096字节,以及cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器端的键值对,有较高的安全性。这就是session。
(4)Session与Cookie结合:cookie弥补了http无状态的不足,让服务器知道来的人是“谁”;但是cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过cookie识别不同的用户,对应的在session里保存私密的信息以及超过4096字节的文本。
(5)django里的Cookie:包含所有cookies的标准Python字典对象;keys和values都是字符串。
(6)django里的session:唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用。
Session与Cookie结合使用:
<1>登录页面:xixi\\app1\\templates\\login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首页</title> <Django Web框架入门