假设我正在建立一个名为ModelController
的班级。我希望这个类有一堆方法可以包装一个单独的Model
类,这是我的数据库抽象。
我希望能够在ModelController
上定义类方法,如下所示:
ModelController():
@classmethod
def list(cls):
cls.model.list()
@classmethod
def byName(cls, name):
return cls.model(name)
让Model类像这样:
ArticleModel(Model):
pass
然后做这样的事情:
ArticleModelController(ModelController):
# ??? maybe:
# model = ArticleModel
我想我可以将我的Model类继承为控制器,然后使用某种mixin模式,但我希望模型成为控制器的类属性的原因是我真的不想冒险当我在一个cherrypy方法调度程序或类似的东西中挂载这个类时,通过HTTP公开它的一些方法。
也许我正在做一些从根本上说不是pythonic或犯下某种谬误的事情。我想做'魔术'吗?
编辑:我只记得我过去的Django及其ModelForms。他们的工作方式如下:
class ArticleForm(ModelForm):
class Meta:
model = Article
也许这就是我应该关注的内容。是否有可能验证此“模型”属性是否已定义,如果某些内容未被定义,则会抛出错误?
答案 0 :(得分:2)
此是元类:
class ModelControllerMetaclass(type):
def __init__(cls, name, bases, dct):
if 'options' not in dct or not hasattr(dct['options'], 'model'):
raise RuntimeError('You accidentally the model!')
dct['_model'] = dct['options'].model
# Some more manipulation of dct['options']
del dct['options']
type.__init__(cls, name, bases, dct)
class ModelController(object):
__metaclass__ = ModelControllerMetaclass
class options:
model = None
class ArticleModelController(ModelController):
class options:
model = 'Some model goes here'
class InvalidModelController(ModelController):
pass
跑步时:
$ python t.py
Traceback (most recent call last):
File "t.py", line 19, in <module>
class InvalidModelController(ModelController):
File "t.py", line 4, in __init__
raise RuntimeError('You accidentally the model!')
RuntimeError: You accidentally the model!
答案 1 :(得分:0)
我想我已经弄明白了。我认为元类可能是解决方案,但我读了很多东西说你可能做错了,除非你肯定知道你需要一个元类。不过,它给出了我想要的确切行为。这是我的ModelController
课程:
class ModelController():
@classmethod
def list(cls):
return cls.meta.model.list()
def __init__(self):
self.model = self.__class__.meta.model
然后我可以有一个模型:
class ArticleModel():
@classmethod
def list(cls):
# logic to retrieve the list of things fitting this class
最后,在我的实际Controller
中,我将在cherrypy
中安装:
class ArticleController():
class meta:
model = ArticleModel
def index(self):
article_list = self.model.list()
return render(article_list)
index.exposed = True
这是邪恶吗?它是魔术还是不够明确?我的Ruby根源显示了吗?从这一点开始,我需要做的就是定义新的模型和控制器,如果我忘记在我的控制器的元类中定义model
属性,当我的挂载方法尝试调用东西时会抛出错误模特。