django-tables2 从 hstore 添加动态列到 table class
django-tables2 add dynamic columns to table class from hstore
我的一般问题是:我可以使用存储在 HStoreField (Django 1.8.9) to generate columns dynamically for an existing Table class of django-tables2 中的数据吗?作为下面的示例,假设我有一个模型:
from django.contrib.postgres import fields as pgfields
GameSession(models.Model):
user = models.ForeignKey('profile.GamerProfile')
game = models.ForeignKey('games.Game')
last_achievement = models.ForeignKey('games.Achievement')
extra_info = pgfields.HStoreField(null=True, blank=True)
现在,假设我有一个 table 定义为:
GameSessionTable(tables.Table):
class Meta(BaseMetaTable):
model = GameSession
fields = []
orderable=False
id = tables.LinkColumn(accessor='id', verbose_name='Id', viewname='reporting:session_stats', args=[A('id')], attrs={'a':{'target':'_blank'}})
started = DateTimeColumn(accessor='startdata.when_started', verbose_name='Started')
stopped = DateTimeColumn(accessor='stopdata.when_stopped', verbose_name='Stopped')
game_name = tables.LinkColumn(accessor='game.name', verbose_name='Game name', viewname='reporting:game_stats', args=[A('mainjob.id')], attrs={'a':{'target':'_blank'}})
我希望能够为所有 GameSession
的 extra_info 列中存储的每个键添加列。我试图覆盖 GameSessionTable class 的 init() 方法,我可以在其中访问查询集,然后制作一组我的 [=15] 的所有键=] 对象,然后将它们添加到 self
,但这似乎不起作用。代码如下:
def __init__(self, data, *args, **kwargs):
super(GameSessionTable, self).__init__(data, *args, **kwargs)
if data:
extra_cols=[]
# just to be sure, check that the model has the extra_info HStore field
if data.model._meta.get_field('extra_info'):
extra_cols = list(set([item for q in data if q.extra_info for item in q.extra_info.keys()]))
for col in extra_cols:
self.columns.columns[col] = tables.Column(accessor='extra_info.%s' %col, verbose_name=col.replace("_", " ").title())
顺便提一下,我看过 https://spapas.github.io/2015/10/05/django-dynamic-tables-similar-models/#introduction 但没什么帮助,因为那里的用例与模型的字段相关,而我的情况如您所见略有不同以上。
只是想检查一下,这是否可能,或者我是否必须为此数据定义一个完全不同的 table,或者可能使用一个完全不同的库,如 django-reports-builder?
设法在一定程度上解决了这个问题。我上面 运行ning 的代码 稍微 错误,所以我将其更新为 运行 我在 superclass 之前的代码init() 获取 运行,并更改了我添加列的位置。
因此,我的 init() 函数现在看起来像这样:
def __init__(self, data, *args, **kwargs):
if data:
extra_cols=[]
# just to be sure, check that the model has the extra_info HStore field
if data.model._meta.get_field('extra_info'):
extra_cols = list(set([item for q in data if q.extra_info for item in q.extra_info.keys()]))
for col in extra_cols:
self.base_columns[col] = tables.Column(accessor='extra_info.%s' %col, verbose_name=col.replace("_", " ").title())
super(GameSessionTable, self).__init__(data, *args, **kwargs)
请注意,我将 self.columns.columns(它们是 BoundColumn 实例)替换为 self.base_columns。这允许 superclass 在初始化 Table
class.
时也考虑这些
可能不是最优雅的解决方案,但它似乎对我有用。
我的一般问题是:我可以使用存储在 HStoreField (Django 1.8.9) to generate columns dynamically for an existing Table class of django-tables2 中的数据吗?作为下面的示例,假设我有一个模型:
from django.contrib.postgres import fields as pgfields
GameSession(models.Model):
user = models.ForeignKey('profile.GamerProfile')
game = models.ForeignKey('games.Game')
last_achievement = models.ForeignKey('games.Achievement')
extra_info = pgfields.HStoreField(null=True, blank=True)
现在,假设我有一个 table 定义为:
GameSessionTable(tables.Table):
class Meta(BaseMetaTable):
model = GameSession
fields = []
orderable=False
id = tables.LinkColumn(accessor='id', verbose_name='Id', viewname='reporting:session_stats', args=[A('id')], attrs={'a':{'target':'_blank'}})
started = DateTimeColumn(accessor='startdata.when_started', verbose_name='Started')
stopped = DateTimeColumn(accessor='stopdata.when_stopped', verbose_name='Stopped')
game_name = tables.LinkColumn(accessor='game.name', verbose_name='Game name', viewname='reporting:game_stats', args=[A('mainjob.id')], attrs={'a':{'target':'_blank'}})
我希望能够为所有 GameSession
的 extra_info 列中存储的每个键添加列。我试图覆盖 GameSessionTable class 的 init() 方法,我可以在其中访问查询集,然后制作一组我的 [=15] 的所有键=] 对象,然后将它们添加到 self
,但这似乎不起作用。代码如下:
def __init__(self, data, *args, **kwargs):
super(GameSessionTable, self).__init__(data, *args, **kwargs)
if data:
extra_cols=[]
# just to be sure, check that the model has the extra_info HStore field
if data.model._meta.get_field('extra_info'):
extra_cols = list(set([item for q in data if q.extra_info for item in q.extra_info.keys()]))
for col in extra_cols:
self.columns.columns[col] = tables.Column(accessor='extra_info.%s' %col, verbose_name=col.replace("_", " ").title())
顺便提一下,我看过 https://spapas.github.io/2015/10/05/django-dynamic-tables-similar-models/#introduction 但没什么帮助,因为那里的用例与模型的字段相关,而我的情况如您所见略有不同以上。
只是想检查一下,这是否可能,或者我是否必须为此数据定义一个完全不同的 table,或者可能使用一个完全不同的库,如 django-reports-builder?
设法在一定程度上解决了这个问题。我上面 运行ning 的代码 稍微 错误,所以我将其更新为 运行 我在 superclass 之前的代码init() 获取 运行,并更改了我添加列的位置。
因此,我的 init() 函数现在看起来像这样:
def __init__(self, data, *args, **kwargs):
if data:
extra_cols=[]
# just to be sure, check that the model has the extra_info HStore field
if data.model._meta.get_field('extra_info'):
extra_cols = list(set([item for q in data if q.extra_info for item in q.extra_info.keys()]))
for col in extra_cols:
self.base_columns[col] = tables.Column(accessor='extra_info.%s' %col, verbose_name=col.replace("_", " ").title())
super(GameSessionTable, self).__init__(data, *args, **kwargs)
请注意,我将 self.columns.columns(它们是 BoundColumn 实例)替换为 self.base_columns。这允许 superclass 在初始化 Table
class.
可能不是最优雅的解决方案,但它似乎对我有用。