Quantcast
Viewing all articles
Browse latest Browse all 9596

我们谈谈 Django 的 ”脸“

Views模块 DJANGO 的脸

Views模块并不是Django中必须的,但是它的存在简化了Django的开发。

因为类 django.core.handlers.base.BaseHandler 中 get_response() 方法会回调views中的方法,并要求返回HttpResponse。 所以只要符合下面格式的方法,都能作为views方法:

from django.http import HttpResponse
def view_func(request, *args, **kwargs):
return HttpResponse("html content")

代码组织:

django/views/
├── csrf.py
├── debug.py
├── decorators
│ ├── cache.py
│ ├── csrf.py
│ ├── gzip.py
│ ├── http.py
│ ├── __init__.py
│ └── vary.py
├── defaults.py
├── generic
│ ├── base.py
│ ├── create_update.py
│ ├── date_based.py
│ ├── dates.py
│ ├── detail.py
│ ├── edit.py
│ ├── __init__.py
│ ├── list_detail.py
│ ├── list.py
│ └── simple.py
├── i18n.py
├── __init__.py
└── static.py view decorators

decorators中封装的函数和装饰器,可以非常方便的使用于reponse的压缩、安全、缓存设置。

gzip.py

我在开发api的时候,就经常用gzip,只要简单的一行,就可以返回gzip压缩后的response(如果在 settings.middleware 中设置了 django.middleware.gzip.GZipMiddleware ,则会自动压缩):

from django.views.decorators.gzip import gzip_page
@gzip_page
def view_func(request):
res = {...}
return HttpResponse(simplejson.dumps(res), mimetype="application/json; charset=utf-8")

方法 django.views.decorators.gzip.gzip_page 其实很简单,它直接用 django.middleware.gzip.GZipMiddleware 包装了当前的view方法。

from django.utils.decorators import decorator_from_middleware
from django.middleware.gzip import GZipMiddleware
gzip_page = decorator_from_middleware(GZipMiddleware)
gzip_page.__doc__ = "Decorator for views that gzips pages if the client supports it."

类 django.middleware.gzip.GZipMiddleware 则处理了view返回的response,进行了gzip压缩,并设置相应的header。

re_accepts_gzip = re.compile(r'\bgzip\b')
class GZipMiddleware(object):
# 处理views_func返回的response
def process_response(self, request, response):
# 判断是否已经压缩过
# 判断是否Accept-Encoding是否有gzip
# 对IE做特殊处理
# ....
# 压缩content, 设置header信息
response.content = compress_string(response.content)
response['Content-Encoding'] = 'gzip'
response['Content-Length'] = str(len(response.content))
return response csrf.py

Django CSRF与Gzip一样,最终也是调用middleware。

源代码中的原理是:

第一次请求返回reponse的时候生成csrf写入cookie。(默认的key为’csrftoken’,也可以通过 settings.CSRF_COOKIE_NAME 来指定) 第一次请求render template的时候在POST表单中,写入 <input type="hidden" name="csrfmiddlewaretoken" value="$csrf_token"/> 提交的时候检查 $request.COOKIES['csrftoken'] == $request.POST['csrfmiddlewaretoken'] ,如果相等则通过,不相等则forbiden。 cache.py

通过 get_cache() 获取settings中配置的cache,中间件 django.middleware.cache.CacheMiddleware 在 process_request() 中获取cache,在 process_response() 中写入cache。

http.py

包含了 处理Etag和Last-Modified头,限制HTTP Method的装饰器。

generic view

django自动生成增、删、改、查、列表页面的视图类。它将web的基本操作进行了基本的封装,虽然灵活性降低了,但是用户写的代码更少了。

generic view中包含3中类型: * View: 视图类,控制增删改查逻辑 * TemplateResponseMixin: 模板类,控制渲染模板 * ObjectMixin: 控制要传入的数据

用法可以参考: Class-based generic views

basic views 的继承关系图:


Image may be NSFW.
Clik here to view.
我们谈谈 Django 的 ”脸“

View

所有视图类的基类。使用dispatch()选择调用view的get post put delete head方法。

http_method_names = ['get', 'post', 'put', 'delete', 'head', 'options', 'trace']
def dispatch(self, request, *args, **kwargs):
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
self.request = request
self.args = args
self.kwargs = kwargs
return handler(request, *args, **kwargs) RedirectView

重定向视图。返回HTTP redirect (301 or 302), 重定向到一个新的url

def get(self, request, *args, **kwargs):
url = self.get_redirect_url(**kwargs)
if url:
if self.permanent:
return http.HttpResponsePermanentRedirect(url)
else:
return http.HttpResponseRedirect(url)

使用方法:

urlpatterns = patterns('',
(r'^oldname/(P<id>.*)$', RedirectView.as_view( url="/newname/%{id}s" ) ),
) TemplateView

渲染指定的模板。这是一个多继承类,继承自 TemplateResponseMixin 和 View ,根据传入的数据和模板名称,执行 render_to_response() 返回。

class TemplateResponseMixin(object):
def render_to_response(self, context, **response_kwargs):
return self.response_class(
request = self.request,
template = self.get_template_names(),
context = context,
**response_kwargs
)
class TemplateView(TemplateResponseMixin, View):
def get_context_data(self, **kwargs):
return {
'params': kwargs
}
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
return self.render_to_response(context) DetailView

察看对象详细信息


Image may be NSFW.
Clik here to view.
我们谈谈 Django 的 ”脸“

ListView

显示对象列表


Image may be NSFW.
Clik here to view.
我们谈谈 Django 的 ”脸“

FormView

显示Form


Image may be NSFW.
Clik here to view.
我们谈谈 Django 的 ”脸“

CreateView

创建对象


Image may be NSFW.
Clik here to view.
我们谈谈 Django 的 ”脸“

UpdateView

编辑更新对象


Image may be NSFW.
Clik here to view.
我们谈谈 Django 的 ”脸“

DeleteView

删除对象


Image may be NSFW.
Clik here to view.
我们谈谈 Django 的 ”脸“


Viewing all articles
Browse latest Browse all 9596

Trending Articles