IordanouGiannis
IordanouGiannis

Reputation: 4357

How do I customize a column based on its value?

Using django-tables2 is very easy from your model to get a table. In my case I need one of my table columns to be formated based on its value.

In my current html table it would look like below:

{% if record.status|stringformat:"s" == "New" %}
    <td class="bg-success></td>

If the value is New the cell background should be green.

From what I could find there are maybe 3 ways to do something like this:

Updated solutions:

1.Create a class and a css rule with the appropriate background color and add it to the column:

class MyTable(tables.Table):    
    status = tables.Column(attrs={"class": lambda record: record.status})

.New {
background-color: green
}

This way it works, although I think that record.status could work, without the lambda.

2.You can specify how to render a column:

class MyTable(tables.Table):    
    status = tables.Column()

    def render_status(self, value):
        if value.name == "New":
            change class accordingly

The change class accordingly part eludes me.

Also you can create a custom column:

class StatusColumn(tables.Column):
    def render(self, value):
        if value == "New":
            return format_html('<span class="text-success">{}</span>', value)

I made this work using a span tag to pass a bootstrap class to format the cell.

3.Use a TemplateColumn and pass html:

class MyTable(tables.Table):  
    status = tables.TemplateColumn("""
    {% if record.status|stringformat:"s" == "New" %}
        <td class="bg-success"></th>
    {% else %}
        <td class="bg-danger"></th>
    {% endif %}
    """)

This way a new column is created formated correctly.

I am still searching how to do this and I would appreciate any help.

Upvotes: 1

Views: 1716

Answers (1)

Jieter
Jieter

Reputation: 4229

Depending on what your exact needs are, there are different solutions.

1. Changing the appearance of the cell (<td></td>)

If you want to add attributes to the <td> tag, you must use something django-tables2 calls column attributes.

It supports fixed values, but also allows a callable to use some value of the record being rendered. Say for instance, you have a record containing a field color and you want to use that color as the background color for the cell.

class Table(tables.Table):
    person = tables.Column(attrs={
        'td': {
            'class': 'person-column',
            'style': lambda record: 'background-color: {}'.format(record.color)
        }
    })

Or more specifically for your example:

class MyTable(tables.Table):    
    status = tables.Column(attrs={'td': {'class': lambda value: 'bg-success' if value == 'New' else 'bg-danger' }})

or without lambda:

def status_attr(record):
    return 'bg-success' if value == 'New' else 'bg-danger'

class MyTable(tables.Table):    
    status = tables.Column(attrs={'td': {'class': status_attr}})

2. changing the contents of the cell

By contents I mean everything within the <td></td> tag. The API of django-tables2 allows for various ways to change the contents of a cell, which is called custom data in the documentation.

Your solutions 2 and 3 already show the ways to do that, however, you can not change the cell attributes in those ways. You might be able to achieve output looking like this <td><td class="bg-success">...</td></td>, which might look like what you want, but are not valid HTML.

Upvotes: 2

Related Questions