chefhose
chefhose

Reputation: 2694

Flask: Make row of Dataframe.to_html() clickable

I have Dataframes generated automatically which shows some data. I want to link each of the rows to a route '/row_details with some of the colums sent as parameters.

@app.route('/')
def index():
    df = get_df()
    return render_template('table.html',  tables=[df.to_html(classes='data')])

@app.route('/row_details')
def row_details():
    column1 = request.args.get('column1')
    column2 = request.args.get('column2')
    #do something with those columns

I guess I could generate a new column for the dataframe consisting of the URL + GET parameters, but is there a nicer way to make the whole row clickable?

The important part of the template looks like that right now:

{% for table in tables %}
       {{ table|safe }}
{% endfor %}

Upvotes: 0

Views: 1588

Answers (1)

furas
furas

Reputation: 142631

If you want to format columns separatelly - without joining values from two columns - then you can use formatters in to_html()

You had to use also escape=False if you want to put HTML in column. Normally it converts < > to &gt; &lt;

BTW: I had to also set 'display.max_colwidth' because it was truncating text in column.

import pandas as pd

df = pd.DataFrame({'url':[
    'https://stackoverflow.com',
    'https://httpbin.org',
    'https://toscrape.com',
]})

pd.set_option('display.max_colwidth', -1)
result = df.to_html(formatters={'url':lambda x:f'<a href="{x}">{x}</a>'}, escape=False)

print(result)

Result:

<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>url</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td><a href="https://stackoverflow.com">https://stackoverflow.com</a></td>
    </tr>
    <tr>
      <th>1</th>
      <td><a href="https://httpbin.org">https://httpbin.org</a></td>
    </tr>
    <tr>
      <th>2</th>
      <td><a href="https://toscrape.com">https://toscrape.com</a></td>
    </tr>
  </tbody>
</table>

But if you want to create links using values from two columns then create new column in DataFrame.

Eventually you would have to format all in template (without using to_html)

df = pd.DataFrame({
    'url':[
        'https://stackoverflow.com',
        'https://httpbin.org',
        'https://toscrape.com',
    ],
    'name':[
        'Ask question',
        'Test requests',
        'Learn scraping'
    ]
})

and

<table>
{% for row in dt.iterrows() %}
    <tr><td><a href="{{ row['url'] }}">{{ row['name'] }}</a></td></tr>
{% endfor %}
</table>

Upvotes: 3

Related Questions