First post in this awesome community that I have been reading a long time ago :)
I've encountered with a problem when using this fantastic library "django-tables2". When I'm ordering a column by a CharField, it does a case sensitive ordering resulting unexpected behaviour like this:
Iago
Pablo
iago
I want to be ordered in a more natural way:
Iago
iago
Pablo
This is my simplified code for the 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',)
I know in Django 1.8 there is a built-in function Lower to make a insensitive order_by, but it doesn't work with django tables:
contact_last_name = tables.Column(verbose_name="Contact", order_by=(Lower('contact_last_name')))
It results in an exception:
TypeError at /
'Lower' object is not iterable
Has anyone done anything similar with django-tables2?
Thank you!
UPDATE: The solution is to make a annotation in the view with the lowercase fields, an then will be available to order by in the 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',)
And make the proper annotation in the queryset when configuring the table as Alasdair purposed:
inquiries = inquiries.annotate(contact_last_name_lower=Lower('last_name'))
my_table = Hometable(inquiries)
I haven't tried this, and I'm not really familiar with django-tables2 so I don't know whether it will work.
You could try using a new field name e.g. contact_last_name_lower
when setting order_by
for the column.
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',)
Then, when you instantiate the table, annotate the queryset with the lower case field.
queryset = Inquiry.objects.annotate(contact_last_name_lower=Lower('contact_last_name'))
table = Hometable(queryset)