DO: html
前提是必需要配置好django使用jinja2模版,保持與老項目模版引擎一致。 python
Django通用視圖最基礎的類是View,其餘如TemplateView、RedirectView等都繼承自它,具體用法參見:Django 通用視圖 mysql
因爲dj默認是不支持區分get/post方法的,須要用戶本身經過如下拙劣的方式來判斷: web
if request.method == 'GET': doGet elif request.method == 'POST': doPost
參考:python django post get 重構,文中是經過url訪問一個通用的視圖函數來區分,然並卵,這裏不適用。 sql
查看源碼 django.views.generic.base.py,發現 RedirectView 自帶get、post方法,因而我這裏選擇繼承RedirectView來實現: django
from django.http import HttpResponse from django.views.generic import RedirectView from django.shortcuts import render, redirect from lib import db from lib.utils import Storage pool = db.database(dbn='mysql', db='test', user='root', port=3306, host='127.0.0.1', pw='123', charset='UTF8', mincached=1, maxcached=10, maxshared=10, maxconnections=10) class Base(RedirectView): def __init__(self, **kwargs): RedirectView.__init__(self, **kwargs) self.config = dict(static='/static') self.db = pool self.session = None x = self class web: def __init__(self): self.db = db def input(self): tmp_dict = {} if x.request.method == 'GET': parameters = x.request.GET elif x.request.method == 'POST': parameters = x.request.POST for k, v in parameters.items(): if type(v) == list: if len(v) == 0: tmp_dict[k] = None elif len(v) == 1: tmp_dict[k] = v[0] else: tmp_dict[k] = v return Storage(tmp_dict) def seeother(self, url): return redirect(url) self.web = web() def redirect(self, url): return redirect(url) def render(self, template_name, **kwargs): d = dict(**kwargs) d['csrf_token'] = '' d['session'] = self.request.session return render(self.request, template_name, d) def get(self, request, *args, **kwargs): result = self.GET(*args, **kwargs) if isinstance(result, HttpResponse): return result return HttpResponse(result, 'application/json') def GET(self): return def post(self, request, *args, **kwargs): result = self.POST(*args, **kwargs) if isinstance(result, HttpResponse): return result return HttpResponse(result, 'application/json') def POST(self): return
其次要解決db問題,dj默認使用自身的ORM操做DB,不近臃腫難用,並且不利於後期維護,主要是定位問題和SQL優化等。 json
查看web.py的db類時無心中發現一段代碼,頓時心頭一喜: flask
try: # db module can work independent of web.py from webapi import debug, config except: import sys debug = sys.stderr config = storage()
原來db.py能夠獨立使用,不依賴webpy的接口。不由感嘆到,這纔是好的設計! api
上面的base類已經集成了db.py和 dbutils模塊,能夠直接在view中使用db鏈接池。 session
END:
經過一個簡單的包裝類便可將dj模擬成web.py,view類只需繼承該基類而後編寫GET或者POST方法便可;
同時session、request parameter、render方法都已經包裝好,徹底能夠避免在視圖中接觸到dj的API,
直接返回結果無需生成HttpResponse!示例view代碼以下:
from common.base import Base import sys class MainView(Base): def GET(self, id): id = int(id) return self.db.query('SELECT $id', {'id' : id}) def POST(self): form = self.web.input() a = form.get('a') b = form.get('b') return self.render('test.html', a=a, b=b)
之後若是閒的DT想切換到Tornado也徹底不須要改view類的代碼了~
TIPS:
url_patterns = [ django.conf.urls.url(r'^$', Base.as_view()), ]
參考:A Quick Guide to Using Django Class Based Views
同時必須在url_pattern裏將視圖包裝使用:django.contrib.auth.decorators.login_required(Base.as_view())
參考:login_required doesn't work with bound methods、How to require login for django generic views?
這雖然是一個8年前的bug。。。但我使用時發現仍是有點問題,最好的辦法是重寫鑑權裝飾器。
如:auth.login(self.request, user)。參考:Django中內置的權限控制3-Login Logout
只需在表單中加上如下元素便可:(參考:How to csrf_token protection in jinja2 template engine?)
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
PS.
對dj不熟悉,文中不免疏漏,或者有更好的方案,還望指點。
anyway,麻麻不再用擔憂我用什麼web框架了,除了flask……