plumdog / flask_table

Because writing HTML is fiddly and all of your tables are basically the same

Home Page:http://flask-table.readthedocs.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Deprecation warning on Python 3.5

palisadoes opened this issue · comments

Getting a deprecation warning on Python 3.5 wen importing Table and Col. It's related to an import that doesn't appear to be used.

Hopefully this is an easy fix.

$ cat /etc/issue
Ubuntu 16.04.1 LTS \n \l
$ uname -a
Linux nylon 4.4.0-45-generic #66-Ubuntu SMP Wed Oct 19 14:12:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from flask_table import Table, Col
/usr/local/lib/python3.5/dist-packages/flask_table/columns.py:5: ExtDeprecationWarning: Importing flask.ext.babel is deprecated, use flask_babel instead.
 from flask.ext.babel import gettext as _
>>> 

Hi,

I think this may well have been fixed by https://github.com/plumdog/flask_table/pull/65/files, which was released to PyPI as 0.3.3 yesterday. Could you see if upgrading fixes your issue?

(Regardless, stuff like this makes me realise that a changelog would be useful and is something I'm missing.)

That's the version I'm running. I just installed Flask-Table today.

$ pip3 list --format=legacy | grep Flask-Table
Flask-Table (0.3.3)
$

Seems the PR I linked only got half of the problem. Replicated and fix inbound.

Fixed in #69 and 0.3.4 released to PyPI.

I'm pretty sure that should have fixed the problem, but reopen if it hasn't.

Thanks for reporting!

@palisades I've previously framed out an approach to accomplish this. First, I subclass Col for whatever column I want to apply a custom color logic and then use a td_class method I created to apply column rules. This approach can highlight individual cells different colors, based on the particular logic set in td_class. Maybe @plumdog has a better approach but this works pretty well for my use case.

class ContextID(Col):
    """Override the flask_table Col class to include cell level color context
    using bootstrap classes where classes => .active -> 'active',
    .success -> 'success', .warning -> 'warning', .danger -> 'danger'."""

def __init__(self, name, attr=None, **kwargs):
    super(ContextID, self).__init__(name, attr=attr, **kwargs)

def td_class(self, content):
    """Make the bootstrap classes work on individual cell level for
    cell highlighting based on conditionals."""

    ## THIS IS FOR EXAMPLE PURPOSE ONLY

    # all these if statements need customized per the use case
    if content.id == 1:
        return 'danger'

    # all these if statements need customized per the use case
    elif content.id == 2:
        return 'warning'

    # all these if statements need customized per the use case
    elif content.id == 3:
        return 'success'

    else:
        return None

def td(self, item, attr):
    """Override the method to allow cell level classes for formatting"""
    if self.td_class(item) is None:
        return '<td>{}</td>'.format(
            self.td_contents(item, self.get_attr_list(attr)))
    else:
        return '<td class={}>{}</td>'.format(
            self.td_class(item),
            self.td_contents(item, self.get_attr_list(attr)))

@palisadoes @Smewp You definitely can do this with subclassing Col and overriding the td method and passing something like attrs={'class': 'myclass'} to element.

This is probably fine if you just have one column that you want to add a class to, but is potentially a pain if you want to be able to apply this to a range of columns all over your application, in which case you may have to subclass every column class.

The best approach also really depends on whether the class that you're setting on the tds for a column depends on the item, or if they're all the same. Eg, do you want to write code that looks like:

class MyTable(Table):
    mycol = Col(td_attrs={'class': 'warning'})  # this doesn't work at present

which is pretty generic, and I would consider adding support for this.

Or code that looks like:

class TDClassCoMixin(object):

    def td(self, item, attr):
        content = self.td_contents(item, self.get_attr_list(attr))
        td_class = ... # something application specific to get the td class from the item, and/or based on the attr
        attrs = {}
        if td_class:
            attrs['class'] = td_class
        return element('td', content=content, escape_content=False, attrs=attrs)

class MyAppCol(TDClassColMixin, flask_table.Col):
    pass

class MyAppBoolCol(TDClassColMixin, flask_table.BoolCol):
    pass

# and so on for each column class you're using, then import and use these classes rather than the originals from flask_table

And that's all application specific, so I don't think it'll fit so easily into flask table.

Just as an extra thought - and it depends what you're doing - you might want to do this with CSS using nth-child, rather than adding classes to the tds at all.

So TLDR, it really depends on your use case - whether you have one or two specific columns you want to add classes to or loads of them, and whether the classes are the same for every td in a column. I hope the above options help, or you may want to post more info about what you're trying to create. (If so, consider opening a new issue for this.)

@palisadoes Take a look at #71 - in particular at changes in the README and the example which shows how it works in a bit of detail. Does that look like it should do the trick?

@Smewp I agree with @palisadoes that some more about how to customise a Col class would be good - it would probably fit well in the "Subclassing Col" bit of the README (which is just copied into the readthedocs page).

@palisadoes Agreed about changing element_attrs -> column_attrs. Much nicer.

As for coexisting, this shouldn't break any backwards compatibility. Though "attr" is now getting a bit overloaded (attr and attr_list to mean "this is how to get a thing from the python object for this row" and column_attrs, th_attrs, td_attrs to mean "put these key-values into the html element"). Which isn't totally lovely, but "attribute" is the right name in both cases, and I don't think the names are horribly confusing. We could change to column_html_attrs, th_html_attrs, td_html_attrs, maybe, to make the distinction clearer?