最近开始看Django框架,对我来说时间一长必定会忘记,所以还是做做笔记!学Django之前还看了点关于Web框架的原理什么的。。。杂七杂八!!!
0x00 关于Web服务
A. Web间的通信
Web应用的本质就是一套socket服务器,而用户的浏览器就是socket客户端,因而最基本的Web框架就是一套socket的代码。
import socket sk = socket.socket() sk.bind(("127.0.0.1", 80)) sk.listen() while True: conn, addr = sk.accept() data = conn.recv(8096) conn.send(b"OK") conn.close()
而这仅仅通过这一的代码,浏览器依然无法打开这个简单的网页,因为在浏览器与服务端进行通信的时候,有一套HTTP协议,简单的来说就是浏览器与服务器之间的通信必须按照一个标准的写法才可以完成通信。
HTTP协议对收发消息都进行了格式的要求
上面的代码无法打开网页,最主要的原因就是没有回复HTTP请求。而一个请求为什么可以打开这个相应的网页呢?在HTTP GET请求的请求行中,就有URL字段正是通过该字段可以网站对指定网页的访问。其主要是通过获取URL字段,相应的调用该字段的函数,从而发送网页的源码到浏览器中,浏览器通过渲染收到的代码后进行将网页渲染出来。
因而总得来说,Web框架的本质就是Socket之间的通信
B. Socket服务端功能划分
在Socket服务端主要有三件事情要做,首先是响应HTTP请求,并发送响应;其次是根据URL字段的不同,执行不同的函数,从而返回相应的页面;最后,就是通过替换页面中的字符串,从而实现动态网页(比如你访问某个页面,上面可以显示今天的日期,其实你明儿打开的还是同一个HTML文件,仅仅是将日期处的字段替换为了今天的日期而已)。总体概况如下:
- 责与浏览器收发消息(socket通信) –> wsgiref/uWsgi/gunicorn…
- 根据用户访问不同的路径执行不同的函数
- 从HTML读取出内容,并且完成字符串的替换 –> jinja2(模板语言)
C. 关于Web框架的分类
Web框架主要完成的任务就是上面的几个功能,而根据不同的Web实现的不同功能可以分为几个主流的框架类型。
以Tornado框架为代表的框架,则可以实现以上三个功能。
以Django框架为代表的框架,则可以后两个功能,第一个功能则需要第三方模块实现。
以Flask框架为代表的框架,则仅仅实现了第二个功能,第一和第三个功能则需要第三方模块来实现。
0x01 初始Django
A. Django框架的安装
在Django官网中可以看到每个办法的支援时间,看了下Django 1.11 LTS可以支援到明年,所以我安装的就是Django 1.11.8。
pip3 install django==1.11.8
安装好Django后可以在终端输入django-admin来测试看看,是否安装成功。
B. 创建一个Django项目
—命令行方式
django-admin startproject 项目名称
—Pycharm方式
File –> New project –> 左侧选Django –> 右侧填项目路径,并且勾选python.exe
之后在一个新窗口中打开。
C. Django文件目录
—文件结构
创建出来的Django项目的文件结构入下图。
urls.py中,主要存放着URL字段调用函数直接的关系。而函数又放在每个APP中的views.py中。
settings.py中,主要是存放一些Django的配置信息,入安装的APP、连接数据库的信息。
templates文件夹中,主要是方HTML文件的文件夹。
—关于settings.py
刚学python,对于settings.py有2个地方要注意。
首先,注释了settings.py中的’django.middleware.csrf.CsrfViewMiddleware’,这行代码,暂时禁用了csrf中间件,可以方便表单提交测试。
其次,这样你发送了HTML页面到浏览器中,会发现javascript、css、图片等静态文件并没有没有发送过去,因而需要将静态文件夹也发送过去。为了统一规范吧!都建立一个叫做static的文件夹,就是上图的那个文件夹了!之后就要打开settings.py去配置静态文件的路径了。
在STATIC_URL下方,静态文件夹的路径,如果也加static的话,那么可以拷贝下面的配置
STATICFILES_DIRS = [ os.path.join(BASE_DIR, "static") ]
之后在HTML中,将静态文件的路径设置前面加上/static/,入下图
注意这里的static不是文件夹的static,而是 STATIC_URL后面的static,也就无论你的静态文件放在哪个文件夹里,只要在STATICFILES_DIRS的列表中,这里只用写static即可生效,有点类似于静态文件的一个环境变量的总和吧!
D. 关于APP
在Django中,为了方便一个大的Django项目中的管理,通过引出APP的概念来实现一个不同APP管理不同的业务。urls.py中调用调用函数的部分,被调用的函数就放在APP中的views.py里了。
创建APP
在Django项目的根目录中输入以下命令即可创建APP
python manage.py startapp app名字
创建完毕APP之后,一定要到项目settings.py中进行APP的注册,不然会有一堆莫名其妙的问题。
其实可以只写app的名字即可,不过还是推荐写全。
0x02 第一个Django项目
接下来以创建一个简易的图书馆里系统的部分环节为例子,来讲述Django项目的编写。通过上面的内容,已经设置好了STATICFILES_DIRS、创建了APP等。
A 映射URL
Server后端收到HTTP请求后,提取出URL路径,之后将跳转到APP中的views.py文件中去读取相应的函数。这个路径与函数之间的映射关系首先是在项目中的settings.py中设置。
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^publisher-list/', views.publisher_list), url(r'^add-publisher/', views.add_publisher), url(r'^edit-publisher/', views.edit_publisher), url(r'^book-list/', views.book_list), url(r'^add-book/', views.add_book), url(r'^edit-book/', views.edit_book), ]
通过在urlpatterns列表中指定路径及映射函数即可。路径的指示支援正则表达式,所以如果是要域名主页的还,那么可以写r’^$’。
B 编写视图Views
进入对应的APP中的views.py中,定义一个函数,函数名字为之前url映射中的后半部分,传入一个HttpRequest对象,一般情况下默认写为request。忽略下面代码中的ORM部分!!
from django.shortcuts import render, redirect, HttpResponse from app01 import models # Create your views here. def publisher_list(request): if request.GET: id = request.GET.get("id", None) del_obj = models.Publisher.objects.get(id=id) del_obj.delete() ret = models.Publisher.objects.all() return render(request, "publisher_list.html", {"publiser": ret})
这样就创建出了一个最简单的Django项目了!!
C Django三件套render HttpResponse redirect
之前介绍了Web框架的本质其实就3点,关于socket通信和URL映射之前都介绍了,接下来就是给浏览器返回数据了。render、HttpResponse、redirect也是用的最多的三个方法,因而江湖美其名曰“Django”三件套。
a HttpResponse
由于视图(理解为views.py中的函数吧!)必须返回一个 HttpResponse 对象给浏览器,因而HttpResponse 方法就是最简单的直接传入字符串即可,已经被封装的无需转化为bytes对象。
b redirect
redirect就是重定向了,可以直接传入一个路径(如”/book-list/”)也可以直接传入一个网址。
c render
render最简单的方法就是直接返回一个渲染好的html页面
return render(request,"about.html")
这样就可以返回了一个静态的页面给浏览器。
如果要返回一个动态页面就需要在render函数中添加content参数了。具体的三件套的使用示例直接见下面的代码吧!
def edit_publisher(request): id = request.GET.get("id", None) edit_obj = models.Publisher.objects.get(id=id) if request.method == "GET": if id: return render(request, "edit-publisher.html", {"publisher": edit_obj}) else: return HttpResponse("无法选择要编辑的出版社!") else: new_name = request.POST.get("name", None) if new_name != edit_obj.name: edit_obj.name = new_name edit_obj.save() return redirect("/publisher-list/")
至于代码中的动态渲染页面还有ORM框架,等系统学习之后在单独的写笔记吧!!!
哈哈,我最近在考虑学flask或者koa中的一个,现在比较看好基于node js的后端开发,异步简直太棒了
加油大佬,我也准备看看flask~喜欢这类轻量级的东西