首先说说Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的、松耦合的方式连接在一起,模型负责业务对象与数据库的映射(ORM),视图负责与用户的交互(页面),控制器接受用户的输入调用模型和视图完成用户的请求,其示意图如下所示:
Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django的MTV分别是值:
M 代表模型(Model):负责业务对象和数据库的关系映射(ORM)。
T 代表模板 (Template):负责如何把页面展示给用户(html)。
V 代表视图(View):负责业务逻辑,并在适当时候调用Model和Template。
除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template,MTV的响应模式如下所示:
1,Web服务器(中间件)收到一个http请求
2,Django在URLconf里查找对应的视图(View)函数来处理http请求
3,视图函数调用相应的数据模型来存取数据、调用相应的模板向用户展示页面
4,视图函数处理结束后返回一个http的响应给Web服务器
5,Web服务器将响应发送给客户端
这种设计模式关键的优势在于各种组件都是松耦合的。这样,每个由 Django驱动的Web应用都有着明确的目的,并且可独立更改而不影响到其它的部分。
比如,开发者更改一个应用程序中的 URL 而不用影响到这个程序底层的实现。设计师可以改变 HTML页面的样式而不用接触Python代码。
数据库管理员可以重新命名数据表并且只需更改模型,无需从一大堆文件中进行查找和替换。
落到实处,Django的MTV模式相对应的python文件如下:
要真正的欣赏Django,你需要撇开表象来看本质。它启发你得同时也让会让你不知所措。下图显示了在Django应用中一个典型的web请求是如何被处理的。
前面的图片展示了从一个访客的浏览器到Django应用并返回的一个web请求的简单历程。如下是数字标识的路径:
虽然某些细节被省略掉,这个解释应该有助于欣赏Django的高级架构。它也展示了关键的组件所扮演的角色,比如模型,视图,和模板。Django的很多组件都基于这几个广为人知设计模式。
在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,实现二者之间的松耦合,这就是命令模式(Command Pattern)。
命令模式有以下特点:
在Django中,把get和post这些请求的行为抽象成一个HttpRequest类,我们可以通过request实例的method获取行为的类型:
if request.method == 'GET':
do_something()
elif request.method == 'POST':
do_something_else()
Django把返回的行为抽象成HttpResponse类,通过调用HttpResponse的方法
from django.http import HttpResponse
>>> response = HttpResponse("Here's the text of the Web page.")
>>> response = HttpResponse("Text only, please.", content_type="text/plain")
此外,对于不同的数据,Django还分别抽象了相应的类来处理。
Json数据:
from django.http import JsonResponse
>>> response = JsonResponse({'foo': 'bar'})
>>> response.content
b'{"foo": "bar"}'
File数据:
from django.http import FileResponse
>>> response = FileResponse(open('myfile.png', 'rb'))
观察者模式(有时又被称为发布(publish)-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
Django中,存在Singal与dispatch类,分别用来发送和接受信号,实现被观察与观察者的角色。
首先,我们可以定义一个观察者,接收一种特定的信号:
import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])
然后我们可以发送信号,使观察者接收相应的信息:
class PizzaStore(object):
...
def send_pizza(self, toppings, size):
pizza_done.send(sender=self.__class__, toppings=toppings, size=size)
...
此外,Django中也有很多built in的signal类,实现不同的功能。
当一个model执行save()方法,即在model对应的数据库中的一张表插入一条数据的前后发送信号。
当一个model执行delete()方法,即在model对应的数据库中的一张表删除一条数据的前后发送信号。
当model中的一个多对多的关系发生改变时发送信号。
当Django开始或者完成一个HTTP请求的时候发送信号。
在使用Django框架的时候,也许有些追求ROA的码农们可能会吐槽没有REST化支持。在Django Restframework框架中的APIView类中,提供了put(), delete(), patch()方法的支持。
比如,如果你想上传一个文件,对应的view就可以这样写:
class FileUploadView(views.APIView):
parser_classes = (FileUploadParser,)
def put(self, request, filename, format=None):
file_obj = request.data['file']
# ...
# do some stuff with uploaded file
# ...
return Response(status=204)
此外,如果你想再服务器端发送请求,Django Restframework中APIClient类提供了各种方法,get(), post(), put(), patch(), delete(), head() and options()。
from rest_framework.test import APIClient
client = APIClient()
client.post('/notes/', {'title': 'new idea'}, format='json')
总的来说,Django提供的框架使得代码量减少了很多,使得程序员只需关注核心的业务逻辑。更多关于Django的设计原则与最佳实践,在以后的学习中逐渐添加吧。