Flask Приложение Heroku - HTML Таблица без форматирования чисел с плавающей запятой и DateTime - PullRequest
2 голосов
/ 03 августа 2020

Недавно я развернул свое веб-приложение Flask на Heroku, но одна из функций, в частности, не работает, как на моем локальном хосте. Функция извлекает информацию о балансе из Yahoo Finance, сохраняет ее в Pandas DataFrame, преобразует ее в HTML и затем отображает на веб-странице. Однако на Heroku, хотя я не получаю никаких ошибок, вся таблица полностью разделена.

Вы также можете попробовать балансовую часть моего приложения по по этой ссылке , если хотите я хотел бы воочию увидеть, что происходит не так. Заранее благодарим!

Python Код:

import requests
import yahoo_fin.stock_info as si
from flask import render_template
 
def get_balance_sheet(ticker):
    try:
        def get_symbol(symbol):
            url = "http://d.yimg.com/autoc.finance.yahoo.com/autoc?query={}&region=1&lang=en".format(symbol)
            result = requests.get(url).json()
            for x in result['ResultSet']['Result']:
                if x['symbol'] == symbol:
                    return x['name']
        company_name = get_symbol(ticker.upper())
        
        df = si.get_balance_sheet(ticker)
        return render_template('balanceSheetOutput.html', company_name=company_name, tables=[df.to_html(classes='data center table-sortable', index=False)], titles=df.columns.values)
    
    except Exception as e:
        return render_template('error.html', e = e)

HTML Код:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>TradeView - Balance Sheet</title>
    <script src="sort-table.js"></script>
    <link rel="stylesheet" href="sort-table.css">
    <link rel="stylesheet" href="https://unpkg.com/purecss@2.0.3/build/pure-min.css" integrity="sha384-cg6SkqEOCV1NbJoCu11+bm0NvBRc8IYLRGXkmNrqUBfTjmMYwNKPWBTIKyw9mHNJ" crossorigin="anonymous">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<style>
table.center {
  margin-left:auto; 
  margin-right:auto;
}
.table-sortable th {
  cursor: pointer;
}

.table-sortable .th-sort-asc::after {
  content: "\25b4";
}

.table-sortable .th-sort-desc::after {
  content: "\25be";
}

.table-sortable .th-sort-asc::after,
.table-sortable .th-sort-desc::after {
  margin-left: 5px;
}

.table-sortable .th-sort-asc,
.table-sortable .th-sort-desc {
  background: rgba(0, 0, 0, 0.1);
}

table{
  width:100%;
}
.tbl-header{
  background-color: rgba(255,255,255,0.3);
 }
.tbl-content{
  height:300px;
  overflow-x:auto;
  margin-top: 0px;
  border: 1px solid rgba(255,255,255,0.3);
}
th{
  padding: 20px 15px;
  text-align: left;
  font-weight: 500;
  font-size: 12px;
  color: #fff;
  text-transform: uppercase;
}
td{
  padding: 15px;
  text-align: left;
  vertical-align:middle;
  font-weight: 300;
  font-size: 12px;
  color: #fff;
  border-bottom: solid 1px rgba(255,255,255,0.1);
}
</style>
</head>
<body>
<nav>
  <div class="logo">
    <a href="{{ url_for('home') }}">
      <img src="{{url_for('static', filename='img/logo.png')}}">
    </a>
  </div>
  <div class="hamburger">
      <div class="line1"></div>
      <div class="line2"></div>
      <div class="line3"></div>
  </div>
  <ul class="nav-links">
      <li><a class="hover" href="{{ url_for('home') }}">Home</a></li>
      <li><a class="hover" href="{{ url_for('stockData') }}">Stock Data</a></li>
      <li><a class="hover" href="{{ url_for('recommendations') }}">Recommendations</a></li>
      <li><a class="hover" href="{{ url_for('technical_indicators') }}">Technical Indicators</a></li>
      <li><a class="hover" href="{{ url_for('contact') }}">Contact</a></li>
      <li><a class="hover" href="{{ url_for('about') }}">About</a></li>
      <li><button class="login-button" href="#">Login</button></li>
      <li><button class="join-button" href="#">Join</button></li>
  </ul>
</nav>
<div style="padding-top: 105px;">
    <h1 id="title" style="text-align: center;">
      Balance Sheet for {{ company_name }}!
    </h1>
    <div class="tbl-header" style="overflow-x: auto; text-align: center; font-size: 24px;">
        {% for table in tables %}
        {{titles[loop.index]}}
        {{ table|safe }}
      {% endfor %}
    </div>
<script>
const hamburger = document.querySelector(".hamburger");
const navLinks = document.querySelector(".nav-links");
const links = document.querySelectorAll(".nav-links li");

hamburger.addEventListener('click', ()=>{
   //Animate Links
    navLinks.classList.toggle("open");
    links.forEach(link => {
        link.classList.toggle("fade");
    });

    //Hamburger Animation
    hamburger.classList.toggle("toggle");
});

function sortTableByColumn(table, column, asc = true) {
    const dirModifier = asc ? 1 : -1;
    const tBody = table.tBodies[0];
    const rows = Array.from(tBody.querySelectorAll("tr"));

    if (column !== 1) {
            sortedRows = rows.sort((a, b) => {
            const aColText = a.querySelector(`td:nth-child(${ column + 1 })`).textContent.trim();
            const bColText = b.querySelector(`td:nth-child(${ column + 1 })`).textContent.trim();
            
            return aColText > bColText ? (1 * dirModifier) : (-1 * dirModifier);
        })
    }
    else {
            sortedRows = rows.sort((a, b) => {
            const aColPrice = parseFloat(a.querySelector(`td:nth-child(${ column + 1 })`).textContent.trim().replace('$', ''));
            const bColPrice = parseFloat(b.querySelector(`td:nth-child(${ column + 1 })`).textContent.trim().replace('$', ''));
            
            return aColPrice > bColPrice ? (1 * dirModifier) : (-1 * dirModifier);
        })
    }if (column !== 1) {
            sortedRows = rows.sort((a, b) => {
            const aColText = a.querySelector(`td:nth-child(${ column + 1 })`).textContent.trim();
            const bColText = b.querySelector(`td:nth-child(${ column + 1 })`).textContent.trim();
            
            return aColText > bColText ? (1 * dirModifier) : (-1 * dirModifier);
        })
    }
    else {
            sortedRows = rows.sort((a, b) => {
            const aColPrice = parseFloat(a.querySelector(`td:nth-child(${ column + 1 })`).textContent.trim().replace('$', ''));
            const bColPrice = parseFloat(b.querySelector(`td:nth-child(${ column + 1 })`).textContent.trim().replace('$', ''));
            
            return aColPrice > bColPrice ? (1 * dirModifier) : (-1 * dirModifier);
        })
    }

    // Remove all existing TRs from the table
    while (tBody.firstChild) {
        tBody.removeChild(tBody.firstChild);
    }

    // Re-add the newly sorted rows
    tBody.append(...sortedRows);

    // Remember how the column is currently sorted
    table.querySelectorAll("th").forEach(th => th.classList.remove("th-sort-asc", "th-sort-desc"));
    table.querySelector(`th:nth-child(${ column + 1})`).classList.toggle("th-sort-asc", asc);
    table.querySelector(`th:nth-child(${ column + 1})`).classList.toggle("th-sort-desc", !asc);
}

document.querySelectorAll(".table-sortable th").forEach(headerCell => {
    headerCell.addEventListener("click", () => {
        const tableElement = headerCell.parentElement.parentElement.parentElement;
        const headerIndex = Array.prototype.indexOf.call(headerCell.parentElement.children, headerCell);
        const currentIsAscending = headerCell.classList.contains("th-sort-asc");

        sortTableByColumn(tableElement, headerIndex, !currentIsAscending);
    });
});
</script>
<script
    src="{{ url_for('static',filename='js/boostraps.js') }}">
</script>
<script
    src="{{ url_for('static',filename='js/bootstrap.min.js') }}">
</script>
<script
    src="{{ url_for('static',filename='js/main.js') }}">
</script>
<script>
$(window).on("load resize ", function() {
  var scrollWidth = $('.tbl-content').width() - $('.tbl-content table').width();
  $('.tbl-header').css({'padding-right':scrollWidth});
}).resize();
</script>
</body>
</html>

Скриншоты Imgur: Скриншоты LocalHost Скриншот приложения Heroku

...