在 django-tables2 中排序不区分大小写
Ordering case insensitive in django-tables2
第一个 post 在我很久以前阅读的这个很棒的社区中:)
我在使用这个很棒的库时遇到了问题 "django-tables2"。当我按 CharField 对列进行排序时,它会进行区分大小写的排序,从而导致如下意外行为:
Iago
Pablo
iago
我想以更自然的方式被点菜:
Iago
iago
Pablo
这是我对 table:
的简化代码
class Inquiry(models.Model):
...
contact_last_name = models.CharField(max_length=50)
...
class Hometable(tables.Table):
contact_last_name = tables.Column(verbose_name="Contact", order_by=('contact_last_name'))
class Meta:
model = Inquiry
fields= ('contact_last_name',)
我知道在 Django 1.8 中有一个内置函数 Lower 可以使不敏感 order_by,但它不适用于 django tables:
contact_last_name = tables.Column(verbose_name="Contact", order_by=(Lower('contact_last_name')))
导致异常:
TypeError at /
'Lower' object is not iterable
有人用 django-tables2 做过类似的事情吗?
谢谢!
更新:解决方案是在视图中使用小写字段进行注释,然后可以在 table 中进行排序。
class Inquiry(models.Model):
...
contact_last_name = models.CharField(max_length=50)
...
class Hometable(tables.Table):
contact_last_name = tables.Column(verbose_name="Contact", order_by=('contact_last_name_lower'))
class Meta:
model = Inquiry
fields= ('contact_last_name',)
并在按照 Alasdair 的目的配置 table 时在查询集中进行适当的注释:
inquiries = inquiries.annotate(contact_last_name_lower=Lower('last_name'))
my_table = Hometable(inquiries)
我没试过这个,我对 django-tables2 也不是很熟悉,所以我不知道它是否行得通。
您可以尝试使用新的字段名称,例如contact_last_name_lower
为列设置 order_by
时。
class Hometable(tables.Table):
contact_last_name = tables.Column(verbose_name="Contact", order_by=('contact_last_name_lower',))
class Meta:
model = Inquiry
fields= ('contact_last_name',)
然后,当您实例化 table 时,用小写字段注释查询集。
queryset = Inquiry.objects.annotate(contact_last_name_lower=Lower('contact_last_name'))
table = Hometable(queryset)
在 https://django-tables2.readthedocs.io/en/latest/pages/ordering.html#table-order-foo-methods 的基础上,您需要添加一个 table.order_FOO() method
并以如下形式结束:
class Hometable(tables.Table):
contact_last_name = tables.Column(verbose_name="Contact", order_by=('contact_last_name'))
def order_contact_last_name (self, QuerySet, is_descending):
QuerySet = QuerySet.annotate(
field_lower=Func(F('contact_last_name '), function='LOWER')
).order_by(('-' if is_descending else '') + 'field_lower')
return (QuerySet, True)
class Meta:
model = Inquiry
fields= ('contact_last_name',)
当您单击 headers 列进行订购以及初始订购时,这应该有效。
第一个 post 在我很久以前阅读的这个很棒的社区中:)
我在使用这个很棒的库时遇到了问题 "django-tables2"。当我按 CharField 对列进行排序时,它会进行区分大小写的排序,从而导致如下意外行为:
Iago
Pablo
iago
我想以更自然的方式被点菜:
Iago
iago
Pablo
这是我对 table:
的简化代码class Inquiry(models.Model):
...
contact_last_name = models.CharField(max_length=50)
...
class Hometable(tables.Table):
contact_last_name = tables.Column(verbose_name="Contact", order_by=('contact_last_name'))
class Meta:
model = Inquiry
fields= ('contact_last_name',)
我知道在 Django 1.8 中有一个内置函数 Lower 可以使不敏感 order_by,但它不适用于 django tables:
contact_last_name = tables.Column(verbose_name="Contact", order_by=(Lower('contact_last_name')))
导致异常:
TypeError at /
'Lower' object is not iterable
有人用 django-tables2 做过类似的事情吗?
谢谢!
更新:解决方案是在视图中使用小写字段进行注释,然后可以在 table 中进行排序。
class Inquiry(models.Model):
...
contact_last_name = models.CharField(max_length=50)
...
class Hometable(tables.Table):
contact_last_name = tables.Column(verbose_name="Contact", order_by=('contact_last_name_lower'))
class Meta:
model = Inquiry
fields= ('contact_last_name',)
并在按照 Alasdair 的目的配置 table 时在查询集中进行适当的注释:
inquiries = inquiries.annotate(contact_last_name_lower=Lower('last_name'))
my_table = Hometable(inquiries)
我没试过这个,我对 django-tables2 也不是很熟悉,所以我不知道它是否行得通。
您可以尝试使用新的字段名称,例如contact_last_name_lower
为列设置 order_by
时。
class Hometable(tables.Table):
contact_last_name = tables.Column(verbose_name="Contact", order_by=('contact_last_name_lower',))
class Meta:
model = Inquiry
fields= ('contact_last_name',)
然后,当您实例化 table 时,用小写字段注释查询集。
queryset = Inquiry.objects.annotate(contact_last_name_lower=Lower('contact_last_name'))
table = Hometable(queryset)
在 https://django-tables2.readthedocs.io/en/latest/pages/ordering.html#table-order-foo-methods 的基础上,您需要添加一个 table.order_FOO() method
并以如下形式结束:
class Hometable(tables.Table):
contact_last_name = tables.Column(verbose_name="Contact", order_by=('contact_last_name'))
def order_contact_last_name (self, QuerySet, is_descending):
QuerySet = QuerySet.annotate(
field_lower=Func(F('contact_last_name '), function='LOWER')
).order_by(('-' if is_descending else '') + 'field_lower')
return (QuerySet, True)
class Meta:
model = Inquiry
fields= ('contact_last_name',)
当您单击 headers 列进行订购以及初始订购时,这应该有效。