0

I am looking for nice solution to make a simple subclassed NumericColumn for my tables, based on django-tables2. I started with that:

class NumericColumn(Column):

    def render(self, value):
        return '{:0,.2f}'.format(value)

It works great until I decided to make negative values red:

class NumericColumn(Column):
    attrs = {
        'td': {
            'class': lambda value: 'text-danger' if value < 0 else ''
        }
    }
    
    def render(self, value):
        return '{:0,.2f}'.format(value)

Code periodically fails with TypeError: '<' not supported between instances of 'str' and 'int', and it seems that lambda function receives already formatted value. I don't see a way to get an original value in record via accessor, and I don't think that it is nice to make a reverse conversion to Decimal for such comparison. Ok, I can test first character for '-', but it is too ugly.

Please help.

SantaFox
  • 11
  • 2
  • Your method's definition looks fine, but how is it used? It looks like the problem comes from another part of your code. Are you sure `value` is actually always an `int`? What's this `record`? – Christophe Jan 12 '22 at 09:25
  • I think that the problem is that `value` seems to come to lambda function already formatted by `render` method, and if I try to convert `value` to `int` or `Decimal`, I receive an error like this: `could not convert string to float: '1,750.40'` – SantaFox Jan 12 '22 at 11:51

2 Answers2

0

The type of value seems string while you are trying to compare it with an integer, so to fix this issue you can just make sure it's converted to float because you are using float value not string.

Change it like this:

lambda value: 'text-danger' if float(value) < 0 else ''
B. Okba
  • 1,021
  • 12
  • 16
  • Thank you for your answer. I thought of course that type of `value` should be specified explicit (I used `Decimal` but there is no difference); however the problem is that `value` seems to come to lambda function already formatted by `render` method, and I receive an error like this: `could not convert string to float: '1,750.40'` – SantaFox Jan 12 '22 at 11:48
0

You may be able to use a solution like the one included in this answer, which uses locale to parse numbers in strings.

For your use, you could try it like this:

(first make sure to import locale and set the appropriate locale. I'm guessing you are using something like US, based on the comma separation of your example number)

import locale
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')

Then:

lambda value: 'text-danger' if locale.atof(value) < 0 else ''
potable
  • 156
  • 1
  • 1
  • 5