Django-tables2:如何order_by访问器

时间:2014-11-18 01:33:58

标签: django sorting sql-order-by django-tables2

假设我们有一个列:

num_member = tables.Column(accessor = 'members.count', verbose_name = 'number of members' )

当我尝试在模板中对此进行排序时,它会引发:

Field Error: Cannot resolve keyword u'count' into field

我阅读了该文档,并说我们可以通过传递某种order_by来使用accessor,但我们到底该怎么做呢?

2 个答案:

答案 0 :(得分:0)

对于Model&#39的属性方法,您可以使用accessor直接访问它。例如:

Class MyModel(models.Model):
    data= models.CharField(max_length=255)

    @property
    def print_function(self):
       return 'hello world'

#Table class
class MyTable(tables.Table):
        data= tables.Column(accessor='print_function')

    class Meta:
        model = MyModel
        fields = ('data')

使用上述方法,您可以使用访问者在表中显示不同类型的数据:

Class SomeModel(models.Model):
    some_data= models.CharField(max_length=255)
    data= models.ManyToManyField(MyModel)

    @property
    def count_function(self):
       some_data= self.data.objects.count() #returns count of the objects
       return some_data

#Table class
class SomeTable(tables.Table):
    data= tables.Column(accessor='count_function')

    class Meta:
        model = SomeModel
        fields = ('data')

并且访问者可以用于直接访问相关的外键模型的字段值,如:

Class SomeModel(models.Model):
    somedata= models.ForeignKey(MyModel)


#Table class
class MyTable(tables.Table):
        data= tables.Column(accessor='somedata.data')

    class Meta:
        model = SomeModel
        fields = ('data')

修改

让我们举一个如何使用order_by的例子:

#Class Based view, I am subclassing ListView and SingleTableView here for example

class MyView(ListView, SingleTableView):
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['table'].order_by = '-last_updated' #last_updated is a datetimefield in model
        return context

在上面的代码中,我所做的是,我在上下文中更改表数据的顺序,稍后将在模板中呈现。

答案 1 :(得分:0)

相当古老的问题,然而,我今天遇到了同样的问题:如果访问者是属性(或0参数方法)而不是模型字段,我无法命令我的表。

在文档中没有找到任何内容并检查源代码后,发现如果tables2的数据是QuerySetkey会将排序传递给数据库,否则它会执行Python列表排序与适当的# django_tables2/tables.py -> class TableData def order_by(self, aliases): # ... if hasattr(self, "queryset"): translate = lambda accessor: accessor.replace(Accessor.SEPARATOR, QUERYSET_ACCESSOR_SEPARATOR) if accessors: self.queryset = self.queryset.order_by(*(translate(a) for a in accessors)) else: self.list.sort(key=OrderByTuple(accessors).key)

try-except

我认为使用if-else而不是QuerySet无法轻易解决这个问题,因为只有在评估查询集后才会引发异常,只会在以后发生。

解决方案:只要您的sort-parameter不是模型字段,在将list交给表之前将get_queryset转换为def get_queryset(self): qs = super(ViewName, self).get_queryset() return list(qs) 。对于django中的许多情况,这将简单到覆盖cached_property

from django.utils.functional import cached_property

@cached_property
def member_count(self):
    # do the heavy stuff here in the model
    return whatever

如果您的访问者在您的表格模型上是num_member = tables.Column( accessor='members_count', verbose_name='number of members' ) ,这应该效果最佳,例如:

imgDelete.Stored := false

然后,在表格中:

<form onsubmit="return(false);">