正在加载...

tornado-9 tornado 和 django 合体(下)

前面,讲述了怎么在tornado中使用django的admin。

但是,一直没有说怎么使用django的orm。

下面来说一说。

orm本身

直接使用django的orm,不管是django的admin还是tornado都是一样的。

事务

直接看Django 1.3 的事务相关的文档

对于commitonsuccess的方式

一定要注意一下:要自动提交,需要django的middleware。

但是django的middelware又只有在django的http环境中才生效,那么对于tornado的http环境,如何生效呢?

大家都知道django的middelware是在进入request之后,和response之前。所以,我们完全可以考虑直接把middelware的方法拿来用。下面是django的traction middelware的源代码

django.middleware.transaction.py

class TransactionMiddleware(object):
    """
    Transaction middleware. If this is enabled, each view function will be run
    with commit_on_response activated - that way a save() doesn't do a direct
    commit, the commit is done when a successful response is created. If an
    exception happens, the database is rolled back.
    """
    def process_request(self, request):
        """Enters transaction management"""
        transaction.enter_transaction_management()
        transaction.managed(True)

    def process_exception(self, request, exception):
        """Rolls back the database and leaves transaction management"""
        if transaction.is_dirty():
            transaction.rollback()
        transaction.leave_transaction_management()

    def process_response(self, request, response):
        """Commits and leaves transaction management."""
        if transaction.is_managed():
            if transaction.is_dirty():
                transaction.commit()
            transaction.leave_transaction_management()
        return response

所以,我们完全可以写这样一个BaseController,用来解决这个问题

base_controller.py

class BaseController(tornado.web.RequestHandler):

    def initialize(self, application, request, **kwargs):
        self.has_except = False

    def prepare(self):
        """Enters transaction management"""
        transaction.enter_transaction_management()
        transaction.managed(True)

    def get_error_html(self, status_code, **kwargs):
        try:
            self.has_except = True
            if transaction.is_dirty():
                transaction.rollback()
            transaction.leave_transaction_management()
        except:
            pass
        finally:
            super(BaseController, self).get_error_html(status_code, **kwargs)

    def finish(self, chunk=None):
        try:
            return super(BaseController, self).finish(chunk=chunk)
        finally:
            if not self.has_except and transaction.is_managed():
                if transaction.is_dirty():
                    transaction.commit()
                transaction.leave_transaction_management()
            django.db.reset_queries()
            django.db.close_connection()

这样就达到了自动提交或者回滚transaction的目的