使用Python的web.py框架实现类似Django的ORM查询的教程

Django中的对象查询

Django框架自带了ORM,实现了一些比较强大而且方便的查询功能,这些功能和表无关。比如下面这个例子:

class Question(models.Model):
  question_text = models.CharField(max_length=200)
  pub_date = models.DateTimeField('date published')

>>> Question.objects.all()
>>> Question.objects.get(pk=1)

从例子可以看出,objects.all和objects.get这些功能都不是在class Question中定义的,可能在其父类models.Model中定义,也可能不是。那么我们在web.py中如何实现这样的功能呢?(如果你选择使用SQLAlchemy就不需要自己实现了)。
实现
思路

我们注意到Question.objects.all()这样的调用是直接访问了类属性objects,并调用了objects属性的方法all()。这里objects可能是一个实例,也可能是一个类。我个人认为(我没看过Django的实现)这应该是一个实例,因为实例化的过程可以传递一些表的信息,使得类似all()这样的函数可以工作。经过分析之后,我们可以列出我们需要解决的问题:

  • 需要实现一个模型的父类Model,实际的表可以从这个父类继承以获得自己没有定义的功能。
  • 实际的模型类(比如Question类)定义后,不实例话的情况下就要具备objects.all()这样的查询效果。
  • 从上面的需求可以看出,我们需要在类定义的时候就实现这些功能,而不是等到类实例化的时候再实现这些功能。类定义的时候实现功能?这不就是metaclass(元类)做的事情嘛。因此实现过程大概是下面这样的:
  • 实现一个Model类,其绑定方法和表的增、删、改有关。
  • 修改Model类的元类为ModelMetaClass,该元类定义的过程中为类增加一个objects对象,该对象是一个ModelDefaultManager类的实例,实现了表的查询功能。

代码

都说不给代码就是耍流氓,我还是给吧。说明下:使用的数据库操作都是web.py的db库中的接口。

  # -*- coding: utf-8 -*-

  import web

  import config # 自定义的配置类,可以忽略

  def _connect_to_db():
    return web.database(dbn="sqlite", db=config.dbname)

  def init_db():
    db = _connect_to_db()
    for statement in config.sql_statements:
      db.query(statement)

  class ModelError(Exception):
    """Exception raised by all models.

    Attributes:
      msg: Error message.
    """

    def __init__(self, msg=""):
      self.msg = msg

    def __str__(self):
      return "ModelError: %s" % self.msg

  class ModelDefaultManager(object):
    """ModelManager implements query functions against a model.

    Attributes:
      cls: The class to be managed.
    """

    def __init__(self, cls):
      self.cls = cls
      self._table_name = cls.__name__.lower()

    def all(self):
      db = _connect_to_db()
      results = db.select(self._table_name)
      return [self.cls(x) for x in results]

    def get(self, query_vars, where):
      results = self.filter(query_vars, where, limit=1)
      if len(results) > 0:
        return results[0]
      else:
        return None

    def filter(self, query_vars, where, limit=None):
      db = _connect_to_db()
      try:
        results = db.select(self._table_name, vars=query_vars, where=where,
                  limit=limit)
      except (Exception) as e:
        raise ModelError(str(e))

      return [self.cls(x) for x in results]

  class ModelMetaClass(type):

    def __new__(cls, classname, bases, attrs):
      new_class = super(ModelMetaClass, cls).__new__(cls, classname,
                              bases, attrs)
      objects = ModelDefaultManager(new_class)
      setattr(new_class, "objects", objects)

      return new_class

  class Model(object):
    """Parent class of all models.
    """

    __metaclass__ = ModelMetaClass

    def __init__(self):
      pass

    def _table_name(self):
      return self.__class__.__name__.lower()

    def insert(self, **kargs):
      db = _connect_to_db()
      try:
        with db.transaction():
          db.insert(self._table_name(), **kargs)
      except (Exception) as e:
        raise ModelError(str(e))

    def delete(self, where, using=None, vars=None):
      db = _connect_to_db()
      try:
        with db.transaction():
          db.delete(self._table_name(), where, vars=vars)
      except (Exception) as e:
        raise ModelError(str(e))

    def save(self, where, vars=None, **kargs):
      db = _connect_to_db()
      try:
        with db.transaction():
          db.update(self._table_name(), where, vars, **kargs)
      except (Exception) as e:
        raise ModelError(str(e))

使用

首先定义表对应的类:

class Users(Model):
  ...

使用就和Django的方式一样:

>>> user_list = Users.objects.all()
(0)

相关推荐

  • Python使用django搭建web开发环境

    安装 Python 去 Python 官方网站找到 Python 3 的下载地址,根据你的系统选择 32 位或者 64 位的安装包,下载好后双击安装即可. 检测是否安装完成 C:\WINDOWS\system32>python -V Python 3.5.2 使用虚拟环境 Virtualenv 安装 Virtualenv C:\WINDOWS\system32>pip install virtualenv 安装成功后就可以开始创建虚拟环境,指定一个你喜欢的目录 C:\WINDOWS\syste

  • Linux系统上Nginx+Python的web.py与Django框架环境

    1.编译nginx 在网上买了一本<实战nginx-取代Apache的高性能服务器>,写的比较浅,主要是些配置方面的东西,不过却正是目前我所需要的.由于需要支持https和rewrite,所以除了nginx的源码之外,又下载了 openssl-0.9.8r.tar.gz 和 pcre-8.12.tar.gz,把他们和nginx-1.0.4.tar.gz放到同一个目录. 为了方便编译,笔者写了一个脚本,代码如下: #!/bin/bash #============================

  • Python之Web框架Django项目搭建全过程

    Python之Web框架Django项目搭建全过程 IDE说明: Win7系统 Python:3.5 Django:1.10 Pymysql:0.7.10 Mysql:5.5 注:可通过pip freeze查看已安装库版本信息. Django 是由 Python 开发的一个免费的开源网站框架,可以用于快速搭建高性能,优雅的网站! Django 特点 强大的数据库功能 用python的类继承,几行代码就可以拥有一个丰富,动态的数据库操作接口(API),如果需要你也能执行SQL语句. 自带的强大的后

  • 全面解读Python Web开发框架Django

    花了两周时间,利用工作间隙时间,开发了一个基于Django的项目任务管理Web应用.项目计划的实时动态,可以方便地被项目成员查看(^_^又重复发明轮子了).从前台到后台,好好折腾了一把,用到:HTML.CSS.JavaScript.Apache.Python.mod_wsgi.Django.好久不用CSS和JavaScript了,感到有点生疏了,查了无数次手册.后台Django开发环境的搭建也花了不少时间和精力.记录下来,免得以后走弯路.同时给大家推荐一下Django框架,如果你想非常快速地编写

  • python常用web框架简单性能测试结果分享(包含django、flask、bottle、tornado)

    测了一下django.flask.bottle.tornado 框架本身最简单的性能.对django的性能完全无语了. django.flask.bottle 均使用gunicorn+gevent启动,单进程,并且关闭DEBUG,请求均只返回一个字符串ok. tornado直接自己启动,其他内容一致. 测试软件为 siege,测试os为cenos6 64位,测试命令为: 复制代码 代码如下: siege -c 100 -r 100 -b http://127.0.0.1:5000/ django

  • Python开发WebService系列教程之REST,web.py,eurasia,Django

    在Bioinformatics(生物信息学)领域,WebService是很重要的一种数据交换技术,未来必将更加重要.目前EBI所提供的WebService就分别有SOAP和REST两种方式的服务,不管是数据服务还是计算服务(计算任务提交). 1 Python + SOAP/WSDL/UDDI 最普遍的做法(个人观点)是使用 python ZSI2.0   ,ZSI还依赖于 SOAPpy  和 pyXML  等LIB. SOAP协议很多人都很熟悉,有很多现有的应用也都使用Java等语言来开发服务端

  • 使用Python的web.py框架实现类似Django的ORM查询的教程

    Django中的对象查询 Django框架自带了ORM,实现了一些比较强大而且方便的查询功能,这些功能和表无关.比如下面这个例子: class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') >>> Question.objects.all() >>> Question.ob

  • 详细解读Python的web.py框架下的application.py模块

    本文主要分析的是web.py库的application.py这个模块中的代码.总的来说,这个模块主要实现了WSGI兼容的接口,以便应用程序能够被WSGI应用服务器调用.WSGI是Web Server Gateway Interface的缩写,具体细节可以查看WSGI的WIKI页面 接口的使用 使用web.py自带的HTTP Server 下面这个例子来自官方文档的Hello World,这个代码一般是应用入口的代码: import web urls = ("/.*", "he

  • 安装Python的web.py框架并从hello world开始编程

    最近有一个小的web项目,想用喜爱都python,但是想到之前接触过都django我感觉一阵不寒而栗,为什么?Django的配置太过复杂,而且小项目不太适合MVC的开发模式,所以我将目光转向了web.py这个小型web框架,并且真正让我动心都是其官方网站上都一句话:"Django lets you write web apps in Django. TurboGears lets you write web apps in TurboGears. Web.py lets you write we

  • 浅析Python的web.py框架中url的设定方法

    网页中的数据在传递的时候有GET和POST两种方式,GET是以网址的形式传参数,在web.py中有着很好的匹配,如果我们配置以下的urls urls =( '/','index', '/weixin/(.*?)','WeixinInterface' ) 先不考虑/weixin/后面的东西,现在我们来写index的类 class index: def GET(self): i = web.input(name = 'kevinkelin',age = 100) return render.inde

  • web.py在SAE中的Session问题解决方法(使用mysql存储)

    这段时间一直想尝试着在SAE中使用Python,初步选择了Web.py框架做为开发框架,但是可怜SAE上的资料少的可怜,有点问题基本上解决不了,今天解决一个Session在Session的存储问题,在SAE中不能直接用本地文件存储,好像是权限的原因,我现在采用的是保存在mysql中,效果也不错.希望对大家有帮助.直接上代码了. index.wsgi #!/usr/bin/env python # coding: utf-8 import os import web import sae from

  • 高性能web服务器框架Tornado简单实现restful接口及开发实例

    有个朋友让我搞搞tornado框架,说实话,这个框架我用的不多... 我就把自己的一些个运维研发相关的例子,分享给大家. 怎么安装tornado,我想大家都懂. pip install tornado 再来说说他的一些个模块,官网有介绍的.我这里再啰嗦的复读机一下,里面掺夹我的理解. 主要模块 web - FriendFeed 使用的基础 Web 框架,包含了 Tornado 的大多数重要的功能,反正你进入就对了. escape - XHTML, JSON, URL 的编码/解码方法 datab

  • Python实现手写一个类似django的web框架示例

    本文实例讲述了Python实现手写一个类似django的web框架.分享给大家供大家参考,具体如下: 用与django相似结构写一个web框架. 启动文件代码: from wsgiref.simple_server import make_server #导入模块 from views import * import urls def routers(): #这个函数是个元组 URLpattern=urls.URLpattern return URLpattern #这个函数执行后返回这个元组

  • Python 搭建Web站点之Web服务器与Web框架

    之前用 Django 做过一个小的站点,感觉Django太过笨重,于是就准备换一个比较轻量级的 Web 框架来玩玩.Web.py 作者已经挂掉,项目好久没有更新,所以不准备用它.而 Flask 也是一个成熟的轻量级 Web 框架,在 github 上有众多的 Star 和 Fork,文档和扩展也很丰富,值得学习. 学习一个框架最好的方式就是用框架做一个项目,在实战中理解掌握框架.这里我用 Flask 框架,使用 Mysql 数据库做了一个 论坛系统 .麻雀虽小,五脏俱全,论坛效果图如下: 论坛系

  • python异步Web框架sanic的实现

    我们继续学习Python异步编程,这里将介绍异步Web框架sanic,为什么不是tornado?从框架的易用性来说,Flask要远远比tornado简单,可惜flask不支持异步,而sanic就是类似Flask语法的异步框架. github:https://github.com/huge-success/sanic 不过sanic对环境有要求: macOS/linux python 3.6+ 不过,我在macOS上安装 sanic 还是踩了坑.依赖库ujson一直安装失败.最后不得不卸载官方py

随机推荐