Django框架自帶了ORM,實(shí)現(xiàn)了一些比較強(qiáng)大而且方便的查詢功能,這些功能和表無(wú)關(guān)。比如下面這個(gè)例子:
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中定義的,可能在其父類(lèi)models.Model中定義,也可能不是。那么我們?cè)趙eb.py中如何實(shí)現(xiàn)這樣的功能呢?(如果你選擇使用SQLAlchemy就不需要自己實(shí)現(xiàn)了)。
實(shí)現(xiàn)
思路
我們注意到Question.objects.all()這樣的調(diào)用是直接訪問(wèn)了類(lèi)屬性objects,并調(diào)用了objects屬性的方法all()。這里objects可能是一個(gè)實(shí)例,也可能是一個(gè)類(lèi)。我個(gè)人認(rèn)為(我沒(méi)看過(guò)Django的實(shí)現(xiàn))這應(yīng)該是一個(gè)實(shí)例,因?yàn)閷?shí)例化的過(guò)程可以傳遞一些表的信息,使得類(lèi)似all()這樣的函數(shù)可以工作。經(jīng)過(guò)分析之后,我們可以列出我們需要解決的問(wèn)題:
代碼
都說(shuō)不給代碼就是耍流氓,我還是給吧。說(shuō)明下:使用的數(shù)據(jù)庫(kù)操作都是web.py的db庫(kù)中的接口。
# -*- coding: utf-8 -*- import web import config # 自定義的配置類(lèi),可以忽略 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))
使用
首先定義表對(duì)應(yīng)的類(lèi):
class Users(Model): ...
使用就和Django的方式一樣:
>>> user_list = Users.objects.all()
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com