web框架
Web应用框架有助于减轻网页开发时共通性活动的工作负荷,例如许多框架提供数据库访问接口、标准样板以及会话管理等,可提升代码的可再用性。简单地说,就是你用别人搭建好的舞台来做表演,用别人做好的模板进行功能扩展。python的web应用框架主要有django,Tornado。
MVC模式和MTV模式
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,JAVA的WEB应用框架就是基于这种模式,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。
M 代表模型(Model):负责业务对象和数据库的关系映射(和MVC模式中的M含义一样)。
T 代表模板 (Template):负责如何把页面展示给用户(html)(和MVC模式中的V含义一样)。
除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template
1. Web服务器接收到用户的http请求
2. Django在URL分发器找到对应的View视图函数处理请求
3. 视图函数View调用相对应的数据模型Model存取数据,调用相对应的模板Template向用户展示页面
4. 视图函数View处理结束后返回一个http的响应给Web服务器
5. Web服务器将响应发送给客户端(各种浏览器)
创建Django工程
File --> New project
点击Create生成以下目录
Views和Urls
打开settings.py,修改INSTALLED_APPS
一个项目一般包含多个应用,一个应用也可以用在多个项目中。
将我们新建的应用(people)添加到 settings.py 中的 INSTALLED_APPS中,也就是告诉Django有这么一个应用。
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'mytest001', # 将我们的application(应用)名称添加到此处,每次新建application(应用)都来此修改 ]
新建的 app 如果不加到 INSTALL_APPS 中的话, django 就不能自动找到app中的模板文件(app-name/templates/下的文件)和静态文件(app-name/static/中的文件) , 后面我们会学习到它们分别用来干什么,先记住。
下面实现一个小功能:打开一个网址,页面会显示“欢迎浏览我的博客”。
打开mytest001/views进行修改
from django.shortcuts import render, HttpResponse # 引入HttpResponse,用来向页面返回内容,类似Python中的print,只不过内容会在网页上显示 # Create your views here. def index(request): # 第一个参数必须是 request,与网页发来的请求有关, # request 变量里面包含get或post的全部内容,用户浏览器,系统等信息在里面 return HttpResponse("欢迎浏览我的博客!") # 函数返回了一个 HttpResponse 对象,可以经过一些处理,最终显示几个字到网页上。
我们的视图函数(View)写完了,那么怎么才能显示呢?
下一步就该定义该视图函数相对应的URL了。
URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码,即访问什么样的网址对应什么样的内容。
打开mysit001/urls进行修改
from django.conf.urls import url from django.contrib import admin from mytest001 import views # 导入views.py urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^myfirstwebpage', views.index) # 添加我们的网址到该list里 ] # 语法: url(正则表达式, views视图函数,参数,别名) # 参数说明: # 一个正则表达式字符串 # 一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串 # 可选的要传递给视图函数的默认参数(字典形式) # 一个可选的name参数
之后点击小三角运行
打开浏览器,输入http://127.0.0.1:8000/myfirstwebpage,就会浏览到想要实现的页面(“8000”为我们在上图中设置的端口号,“myfirstwebpage”为我们在list里添加的符合正则表达式的内容)。
Templates
templates是为了将页面的设计和Python的代码分离开会更干净简洁更容易维护。 我们可以使用 Django的 模板系统 (Template System)来实现这种模式。该文件夹下存放的是HTML文件,用来进行返回页面给用户相对应的请求。
实现一个需求,当打开某个页面时,页面会显示当前时间,下面我们利用tempates来做一下。
打开mysit001/templates文件夹,在文件夹里创建一个名为“myhtml”的HTML文件,代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> {#{{ var }} {{ times }}是一种叫做 模板语言 的语法,一会儿会讲解#} <body> <h1>{{ var }}:{{ times }}</h1> </body> </html>
文件mysit001/mysit001/urls文件不用修改和上次一样,打开mysit001/mytest001/views进行以下修改:
from django.shortcuts import render import time def index(request): times = time.ctime(time.time()) return render(request, "myhtml.html", {"times": times, "var": "当前时间"}) # render() 是HttpRespose对象,用来对页面进行渲染,HttpResponse只是单纯返回HTML语句,如果HTML代码中有变量或者逻辑之类他就无能为力了 # 参数详解: render()的第一个参数必须是传递进来的request对象,第二个参数你想要返回的HTML文件路径(可能你会疑问为什么只返回文件名称就行,下面有解释) # 第三个参数是一个字典,键“key”对应的是HTML文件中的变量名,值“value”是你想给变量的赋值 # 当Django运行时,会首先运行settings.py,打开该文件你会发现以下代码 # BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 上面代码是找到当前项目的最外层目录,而在settings.py中的TEMPLATES中你会找到下面代码 # 'DIRS': [os.path.join(BASE_DIR, 'templates')] # 这句代码就是帮你配置了文件,找到了templates文件夹,render()方法中的第二个参数会与他进行路径拼接,就找到了想要的HTML文件
点击运行,打开浏览器输入http://127.0.0.1:8000/myfirstwebpage你就会发现功能实现了。
小练习,打开网页,输入个人信息,提交后页面下方会显示所有提交过的个人信息,如下图:
mysit001/templates/myhtml.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> {#{% %}内为 模板语言,之后会讲解#} {#form表单中 action代表form表单提交的数据由myhtml页面进行操作 method表示请求方式#} <body> <form action="/myhtml" method="post"> <div> 姓名:<input type="text" name="username"> </div> <div> 性别:<input type="text" name="usersex"> </div> <div> 年龄:<input type="text" name="userage"> </div> <div> <input type="submit" value="提交"> </div> <hr> <table border="1"> <tr> <td>姓名</td> <td>性别</td> <td>年龄</td> </tr> {% for i in user_list %} <tr> <td>{{ i.username }}</td> <td>{{ i.usersex }}</td> <td>{{ i.userage }}</td> </tr> {% endfor %} </table> </form> </body> </html>
mysit001/mysit001/urls.py
from django.conf.urls import url from django.contrib import admin from mytest001 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^myhtml', views.index), # 将URL与视图函数进行关联 ]
mysit001/mytest001/views.py
from django.shortcuts import render, HttpResponse user_list = [] def index(request): if request.method == "POST": # request.method是请求方式 有POST GET 因为在HTML中已经声明提交form表单时用的是POST请求方式,所以这里用这个作为判断条件 username = request.POST.get("username", None) # post请求过来的数据 全部在request.POST中 通过request.POST.get("key")获取 userage = request.POST.get("userage", None) usersex = request.POST.get("usersex", None) user_dic = {"username": username, "userage": userage, "usersex": usersex} user_list.append(user_dic) return render(request, "myhtml.html", {"user_list": user_list}) # "user_list"对应HTML{%%}中的user_list变量 # 如果POST请求 则返回上面 否则返回下面 第一次请求默认GET return render(request, "myhtml.html") # ############ 参数request的属性及方法 # 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" # # # # COOKIES: 包含所有cookies的标准Python字典对象;keys和values都是字符串。 # # 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 # 时该属性才可用 # # session: 唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用。 # 方法 # get_full_path(), 比如:http://127.0.0.1:8000/index33/?name=123 ,req.get_full_path()得到的结果就是/index33/?name=123 # req.path:/index33
找到mysit001/mysit001/settings.py, 找到MIDDLEWARE下的'django.middleware.csrf.CsrfViewMiddleware'并注释。之后运行会看到效果。至于原因,之后会有讲解。
Models
还是上述需求,这次我们将数据存放到数据库进行需求实现,Django自带数据库Sqlite
mysit001/mytest001/models.py
from django.db import models # Create your models here. class userinfo(models.Model): username = models.CharField(max_length=64) userage = models.CharField(max_length=64) usersex = models.CharField(max_length=64)
mysit001/mytest001/views.py
from django.shortcuts import render, HttpResponse from mytest001 import models user_list = [] def index(request): if request.method == "POST": # request.method是请求方式 有POST GET username1 = request.POST.get("username", None) # post请求过来的数据 全部在request.POST中 通过request.POST.get("key")获取 userage1 = request.POST.get("userage", None) usersex1 = request.POST.get("usersex", None) models.userinfo.objects.create( username = username1, userage = userage1, usersex = usersex1 ) user_list = models.userinfo.objects.all() return render(request, "myhtml.html",{"user_list":user_list})
运行前,先在Terminal终端进行数据库初始化
#输入 python manage.py makemigrations #回车 再输入 python manage.py migrate
成功后再运行,浏览器输入地址就会出现实现需求的页面。
整篇文章只是Django初步认识,很多知识点没有细讲,请看下篇博客。
]