我试图在Django中复制类似于模型查询的内容。
# database.py
class ModelFactory(object):
def __init__(self, table):
self.table = table
def fields(self, *args):
str_columns = ''
for count, arg in enumerate(args):
if count == 0:
str_columns += arg
else:
str_columns += ', %s' % arg
self.str_columns = str_columns
def wheres(self, **kwargs):
str_wheres = ''
for count, (key, value) in enumerate(kwargs.items()):
if count == 0:
str_wheres += 'WHERE %s = %s' % (key, value)
else:
str_wheres += ' AND %s = %s' % (key, value)
self.str_wheres = str_wheres
我的想法是按如下方式使用它:
from database import ModelFactory
myInstance = ModelFactory('myTable')
myQuery = myInstance.fields('column1', 'column2').wheres(column1 = 5)
我不确定我是否需要在ModelFactory类中使用新类或函数来获取'字段'并且''s'编译一个SQL字符串来查询?如下所示:
cur.execute('SELECT column1, column2 from myTable WHERE column1 = 5')
我也不确定调用class.function1.function2是否正确? Django拥有'对象'单词,例如Instance.objects.filter()。排除()
我尝试按如下方式更改代码库:
# database.py
class ModelFactory(object):
def __init__(self, table):
self.table = table
def objects(self):
def fields(self, **kwargs):
return self.f(**kwargs)
def wheres(self, *args):
return self.w(*args)
def f(self, *args):
str_columns = ''
for count, arg in enumerate(args):
if count == 0:
str_columns += arg
else:
str_columns += ', %s' % arg
self.str_columns = str_columns
def w(self, **kwargs):
str_wheres = ''
for count, (key, value) in enumerate(kwargs.items()):
if count == 0:
str_wheres += 'WHERE %s = %s' % (key, value)
else:
str_wheres += ' AND %s = %s' % (key, value)
self.str_wheres = str_wheres
但是当我尝试以下内容时:
from database import ModelFactory
myInstance = ModelFactory('myTable')
myQuery = myInstance.objects.fields('column1', 'column2').wheres(column1 = 5)
我得到一个AttributeError:' function'对象没有属性'字段'
答案 0 :(得分:3)
如果要链接对象的方法调用,则需要从方法返回该对象。即将return self
添加到您的方法中。
所以你的类声明可能应该如下所示:
class ModelFactory(object):
def __init__(self, table):
self.table = table
def fields(self, *args):
self.str_columns = ', '.join(args)
return self
def wheres(self, **kwargs):
str_wheres = ' AND '.join('{} = {}'.format(k, v) for k, v in kwargs.items())
self.str_wheres = 'WHERE {}'.format(str_wheres)
return self
def execute(self):
// ATTN! This code is prone to SQL injection. Do not use!
cur.execute('SELECT {columns} FROM {table} {wheres}'.format(columns=self.str_columns, table=self.table, wheres=self.wheres))
答案 1 :(得分:0)
问题是你仍然有objects
作为一个功能:
def objects(self):
目前,这意味着您需要将其称为功能 - 您的myQuery
行需要看起来像:
myQuery = myInstance.objects().fields(...
但是,由于fields
和wheres
仅限于objects
函数范围内,因此仍然不够。
如果你想要按下这条路线,那么你需要创建一个你在模型中在属性objects
下实例化的类 - Django使用QuerySet
来实现。如果你看看source,你会看到制作一些东西需要多少魔法"简单"比如objects
工作。
这是一个简单的替代方案吗?
您必须创建一个类似于QuerySet
的新类,它可以提供fields
和wheres
可链接功能 - 让我们称之为WernerfeuerSet
:< / p>
class WernerfeuerSet:
def __init__(self, table):
self.table = table
def fields(self, **kwargs):
pass
def wheres(self, **kwargs):
pass
现在在你的ModelFactory
中实例化 - 比如:
class ModelFactory:
def __init__(self, table):
self.objects = WernerfeuerSet(table)
现在您的原始查询应该是可能的,因为objects
是ModelFactory
的属性,而不是函数:
myQuery = myInstance.objects.fields('column1', 'column2').wheres(column1 = 5)