rog*_*err 6 python django metaprogramming django-tables2
因此,对于Django项目,我真的希望能够动态地生成和显示表(不基于查询集),而无需事先知道内容或模式.
看起来django-tables2应用程序为呈现表提供了很好的功能,但它要求您通过在自定义的Table子类上声明属性来显式声明列名,或者为它提供推断列的模型.
即,要使用名为"name"的列,您可以:
class NameTable(tables.Table):
name = tables.Column()
Run Code Online (Sandbox Code Playgroud)
Tables类没有提供事后添加列的方法,因为从读取源代码开始,它似乎使用了一个元类来清除__new__上的类属性并锁定它们.
看起来非常简单的元编程将是一个优雅的解决方案.我定义了一个接受列名为参数的基类工厂:
def define_table(columns):
class klass(tables.Table): pass
for col in columns:
setattr(klass, col, tables.Column())
return klass
Run Code Online (Sandbox Code Playgroud)
可悲的是,这不起作用.如果我跑'
x = define_table(["foo", "bar"])(data)
x.foo
x.bar
Run Code Online (Sandbox Code Playgroud)
我回来了:
<django_tables2.columns.base.Column object at 0x7f34755af5d0>
<django_tables2.columns.base.Column object at 0x7f347577f750>
Run Code Online (Sandbox Code Playgroud)
但是,如果我列出列:
print x.base_columns
Run Code Online (Sandbox Code Playgroud)
我什么都没回来,即{}
我意识到可能有更简单的解决方案(例如只是咬紧牙关并在代码中定义每个可能的数据配置,或者不使用django-tables2并自己动手),但我现在将此视为一个了解更多信息的机会元编程,所以我真的想以这种方式工作.
知道我做错了什么吗?我的理论是__new__方法(在元类表使用中重新定义)在定义klass时被调用,而不是在实例化时调用,所以当我对属性进行处理时,为时已晚.但这违反了我对__new__何时应该发生的理解.否则,我很难理解元类__new__如何区分定义代码属性与动态定义属性之间的区别.
谢谢!
您在这里走在正确的轨道上,但不是创建准系统类并向其添加属性,而是应该使用type()内置函数。它没有按照您尝试的方式工作的原因是元类已经完成了它的工作。
Usingtype()允许您使用自己的属性构造一个新类,同时设置基类。含义 - 您可以将想要的字段描述为类的蓝图,允许Tables 元类在您的定义之后接管。
这是type()与 django 一起使用的示例。我自己在我自己的项目中使用了它(有一些细微的变化),但考虑到你已经快到了,它应该给你一个很好的起点。
def define_table(columns):
attrs = dict((c, tables.Column()) for c in columns)
klass = type('DynamicTable', (tables.Table,), attrs)
return klass
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1676 次 |
| 最近记录: |