简体   繁体   English

django-tables2 从 hstore 向表类添加动态列

[英]django-tables2 add dynamic columns to table class from hstore

My general question is: can I use the data stored in a HStoreField (Django 1.8.9) to generate columns dynamically for an existing Table class of django-tables2 ?我的一般问题是:我可以使用存储在HStoreField (Django 1.8.9) 中的数据为django-tables2的现有Table类动态生成列吗? As an example below, say I have a model:作为下面的示例,假设我有一个模型:

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)

Now, say I have a table defined as:现在,假设我有一个表定义为:

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'}})

I want to be able to add columns for each of the keys stored in the extra_info column for all of the GameSession s.我希望能够为所有GameSessionextra_info列中存储的每个键添加列。 I have tried to override the init () method of the GameSessionTable class, where I have access to the queryset, then make a set of all the keys of my GameSession objects, then add them to self , however that doesn't seem to work.我试图覆盖 GameSessionTable 类的init () 方法,在那里我可以访问查询集,然后创建一组我的GameSession对象的所有键,然后将它们添加到self ,但这似乎不起作用. Code below:代码如下:

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())

Just a mention, I have had a look at https://spapas.github.io/2015/10/05/django-dynamic-tables-similar-models/#introduction but it's not been much help because the use case there is related to the fields of a model, whereas my situation is slightly different as you can see above.只是提一下,我看过https://spapas.github.io/2015/10/05/django-dynamic-tables-similar-models/#introduction但它没有多大帮助,因为那里的用例与模型的领域相关,而我的情况与您在上面看到的略有不同。

Just wanted to check, is this even possible or do I have to define an entirely different table for this data, or potentially use an entirely different library altogether like django-reports-builder ?只是想检查一下,这是否可能,或者我是否必须为此数据定义一个完全不同的表,或者可能完全使用一个完全不同的库,如django-reports-builder

Managed to figure this out to a certain extent.设法在一定程度上解决了这个问题。 The code I was running above was slightly wrong, so I updated it to run my code before the superclass init() gets run, and changed where I was adding the columns.我在上面运行的代码有点错误,所以我更新了它以在超类init()运行之前运行我的代码,并更改了添加列的位置。

As a result, my init() function now looks like this:结果,我的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)

Note that I replaced self.columns.columns (which were BoundColumn instances) with self.base_columns .请注意,我换成self.columns.columns(这是绑定列实例)与self.base_columns。 This allows the superclass to then consider these as well when initializing the Table class.这允许超类在初始化Table类时也考虑这些。

Might not be the most elegant solution, but it seems to do the trick for me.可能不是最优雅的解决方案,但它似乎对我有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM