基于django的博客(1)
前记
一开始为了熟悉django而按照教程或者文章写的基于django的博客
一个非常简单的博客实现
github
基本功能
代码量比较少只是简单的实现增删改
- 管理员发表文章
- 访问者查看文章
- 归档
- 标签
- 分类
- 搜索
new
DetailView与ListView
为了减少代码使用量等,在django中可以使用基于view来编写视图。常用的有DetailView与ListView,他们有些细微的却别:
- 主要功能
- ListView-从数据库中获取模型列表的数据
- DetailView从数据库获取模型的一条记录数据。比如查看某篇文章的详情,就是从数据库中获取这篇文章的记录然后渲染模板。
方法:
DetailView 有以下方法:
- dispatch()
- http_method_not_allowed()
- get_template_names()
- get_slug_field()
- get_queryset()
- get_object()
- get_context_object_name()
- get_context_data()
- get()
- render_to_response()
ListView 有以下方法:
- dispatch()
- http_method_not_allowed()
- get_template_names()
- get_queryset()
- get_context_object_name()
- get_context_data()
- get()
- render_to_response()
内部结构:
ListView类图
DetailView类图
在这两个类图中,最关键的组件就是MultiObjectMixin和SingleObjectMixin这两个类了,他们实现的功能是从数据库中读取数据,并且构建要传入template的context。每个类都有一些属性和方法可以覆盖,实现自定制,比如可以覆盖context_object_name变量,用来指定传入template的context的对象的变量名;可以覆盖get_context_data()方法,用来将其他的变量放到context中;为queryset赋值,就可以自己指定这个View操作的对象(列表);或者是直接重写get_queryset()/get_object()方法,简单暴力。
注意,这两个类,也是继承自TemplateResponseMixin,也就是说它们也是直接返回的TemplateResponse对象。
django的处理流程
web server
django拥有一个自己的web server-runserver,主要用于开发和调试中,部署到线上环境时用的都是别的web server 如:nginx+uwsgi
runserver运行时主要是完成以下两件事:
- 解析参数,并通过django.core.servers.basehttp.get_internal_wsgi_application方法获取wsgi handler;
- 根据ip_address和port生成一个WSGIServer对象,接受用户请求
get_internal_wsgi_application的源码如下:
通过上面的代码可知道,Django会先根据settings中的WSGI_APPLICATION来获取handler;
在创建project的时候,Django会默认创建一个wsgi.py文件,而settings中的WSGI_APPLICATION配置也会默认指向这个文件。看一下这个wsgi.py文件,其实它也和上面的逻辑一样,最终调用get_wsgi_application实现。
django http请求处理流程(来源于网上)
Django的具体处理流程大致如下:
加载settings.py
在通过django-admin.py创建project的时候,Django会自动生成默认的settings文件和manager.py等文件,在创建WSGIServer之前会执行下面的引用:
1
from django.conf import settings
上面引用在执行时,会读取os.environ中的DJANGO_SETTINGS_MODULE配置,加载项目配置文件,生成settings对象。所以,在manager.py文件中你可以看到,在获取WSGIServer之前,会先将project的settings路径加到os路径中。
创建WSGIServer
不管是使用哪个web server运行Django项目,在启动时都会调用django.core.servers.basehttp中的run()方法
创建一个django.core.servers.basehttp.WSGIServer类的实例,之后调用其serve_forever()方法启动HTTP服务。
run方法的源码如下:
1 |
|
如上,我们可以看到:在创建WSGIServer实例的时候会指定HTTP请求的Handler,
上述代码使用WSGIRequestHandler。当用户的HTTP请求到达服务器时,
WSGIServer会创建WSGIRequestHandler实例,使用其handler方法来处理HTTP请求(其实最终是调用wsgiref.handlers.BaseHandler中的run方法处理)。
WSGIServer通过set_app方法设置一个可调用(callable)的对象作为application,上面提到的handler方法最终会调用设置的application处理request,并返回response。
其中,WSGIServer继承自wsgiref.simple_server.WSGIServer,而WSGIRequestHandler继承自wsgiref.simple_server.WSGIRequestHandler,wsgiref是python标准库给出的WSGI的参考实现。其源码可自行到wsgiref参看,这里不再细说。
- 处理Request
第二步中说到的application,在Django中一般是django.core.handlers.wsgi.WSGIHandler对象,WSGIHandler继承自django.core.handlers.base.BaseHandler,这个是Django处理request的核心逻辑,它会创建一个WSGIRequest实例,而WSGIRequest是从http.HttpRequest继承而来
- 返回Response
上面提到的BaseHandler中有个get_response方法,该方法会先加载Django项目的ROOT_URLCONF,然后根据url规则找到对应的view方法(类),view逻辑会根据request实例生成并返回具体的response。
在Django返回结果之后,第二步中提到wsgiref.handlers.BaseHandler.run方法会调用finish_response结束请求,并将内容返回给用户
Django处理Request的流程
1.用户通过浏览器输入url请求一个页面
2.请求到达Request Middlewares,中间件对request做一些预处理或者直接response请求(处理包括ip判断用户判断等)
3.URLConf通过urls.py文件和请求的URL的对比,找到相应的View
4.View Middlewares被访问,同样可以对request做一些处理或者直接返回response
5.调用View中的函数,进行逻辑判断
6.如果需要访问数据库获取或修改数据时,则通过Models访问底层的数据
7.view把对应的数据生成一个字典并返回给Template
8.Template接受数据并生成页面
8.1Template使用Filters和Tags去渲染输出
8.2HTTPResponse被发送到Response Middlewares
8.3任何Response Middlewares都可以丰富response或者返回一个完全不同的response
8.4Response返回到浏览器,呈现给用户
Middleware(中间件)
Middleware是在Django BaseHandler的load_middleware方法执行时加载的,加载之后会建立四个列表作为处理器的实例变量:
_request_middleware:process_request方法的列表
_view_middleware:process_view方法的列表
_response_middleware:process_response方法的列表
_exception_middleware:process_exception方法的列表
Django的中间件是在其配置文件(settings.py)的MIDDLEWARE_CLASSES元组中定义的。在MIDDLEWARE_CLASSES中,中间件组件用字符串表示:指向中间件类名的完整python路径。例如
1 |
|
中间件出现的顺序非常重要:在request和view的处理阶段,Django按照MIDDLEWARE_CLASSES中出现的顺序来应用中间件,而在response和exception异常处理阶段,Django则按逆序来调用它们。也就是说,Django将MIDDLEWARE_CLASSES视为view函数外层的顺序包装子:在request阶段按顺序从上到下穿过,而在response则反过来。
URLConf
URLConf相当于Django使用的地图告诉django要怎么去寻找url
第一个参数是url,可以通过正则去比对相应的url。
第二个参数是view,告诉Django如果这个url对应的view
ps:第二个参数也可以是url把匹配到的url导向另一个app下面的url。使得url不会集成于一页,同时可以把二级url区分开
第三个参数是命名空间,告诉那些需要调用url的(如模板),输入这个命名空间的名称就能获取到对应的url
Template
django通过模板把动态数据导入html文件并返回给用户,需要注意的是,模板里不能编写python代码
部署
- 本文作者:So1n
- 本文链接:http://so1n.me/2017/08/23/p1/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!