【问题标题】:Rendering multiple dataframes from API calls in Django Views从 Django 视图中的 API 调用渲染多个数据帧
【发布时间】:2020-12-28 03:39:02
【问题描述】:

我有一个页面,旨在根据客户输入(他们输入他们正在寻找的公司)显示公司财务状况。一旦他们提交,我想在视图函数中创建 5 个 API url,然后获取 json 数据,创建一个包含 1 个 API 结果的日期的列表(它们都将包含相同的日期,所以我将使用相同的列表) ),然后使用来自每个 api 调用的特定数据以及日期列表创建新字典。然后我想为每个字典创建数据帧,然后将每个字典作为 html 呈现给模板。

我的第一次尝试是尝试在“if request.method == 'POST'”块内的 try 块中依次执行所有 requests.get 和 jsons.load 调用。这在仅从一个 API 调用中获取数据时效果很好,但不适用于 5。我会在分配错误之前获得引用的局部变量,这让我认为多个 requests.get 或 json.loads 正在创建错误。

我当前的尝试(出于好奇而创建,以查看它是否以这种方式工作)确实按预期工作,但由于它在 for 循环中多次调用 API,因此不正确,如图所示。 (为简单起见,我取出了一些代码)

def get_financials(request, *args, **kwargs):
    pd.options.display.float_format = '{:,.0f}'.format
    IS_financials = {} #Income statement dictionary
    BS_financials = {} #Balance sheet dictionary
    dates = []

    if request.method == 'POST':
        ticker = request.POST['ticker']
        IS_Url = APIURL1
        BS_URL = APIURL2
        
        try:
            IS_r = requests.get(IS_Url)
            IS = json.loads(IS_r.content)       
    
            for year in IS:
                y = year['date']
                dates.append(y)
            
            for item in range(len(dates)):
                IS_financials[dates[item]] = {}
                IS_financials[dates[item]]['Revenue'] = IS[item]['revenue'] / thousands
                IS_financials[dates[item]]["Cost of Revenue"] = IS[item]['costOfRevenue'] / thousands
                IS_fundementals = pd.DataFrame.from_dict(IS_financials, orient="columns")

            for item in range(len(dates)):
                BS_r = requests.get(BS_URL)
                BS = json.loads(BS_r.content)
                BS_financials[dates[item]] = {}
                BS_financials[dates[item]]['Cash and Equivalents'] = BS[item]['cashAndCashEquivalents'] / thousands
                BS_financials[dates[item]]['Short Term Investments'] = BS[item]['shortTermInvestments'] / thousands
                BS_fundementals = pd.DataFrame.from_dict(BS_financials, orient="columns")
                

        except Exception as e:
            apiList = "Error..."

        return render(request, 'financials.html', {'IS': IS_fundementals.to_html(), 'BS': BS_fundementals.to_html()})
    else:
        return render(request, 'financials.html', {})

我正在想办法做到这一点。我是 django/python 的新手,不太确定此类问题的最佳实践是什么。我曾想过为每个 API 制作单独的函数,但是我无法在同一页面上呈现它们。我可以使用嵌套函数吗?只有主函数呈现给模板,而所有内部函数只是将数据框返回给外部函数?对于这样的事情,基于类的视图会更好吗?我从来没有使用过基于类的视图,所以会有一点学习曲线。

我的另一个问题是如何更改从数据框呈现的表中的 html?当前渲染的表格/字体非常大。

感谢您的任何提示/建议!

【问题讨论】:

    标签: python django django-views django-templates


    【解决方案1】:

    仅将 pandas 用于它的 .to_html() 方法并不常见,但我已经在 django 方法中调用了 pandas 。 更常见的方法是使用 django 模板的循环方法循环 ISBS 对象以生成 html 表。

    为了使此方法更有效,将BS api 调用移出日期循环,只要 API 调用未在日期之前更改。 api 调用的合理超时也会有所帮助。

    def get_financials(request, *args, **kwargs):
        pd.options.display.float_format = '{:,.0f}'.format
        IS_financials = {} #Income statement dictionary
        BS_financials = {} #Balance sheet dictionary
        dates = []
    
        if request.method == 'POST':
            ticker = request.POST['ticker']
            IS_Url = APIURL1
            BS_URL = APIURL2
            
            try:
                IS_r = requests.get(IS_Url, timeout=10)
                IS = json.loads(IS_r.content)
                BS_r = requests.get(BS_URL, timeout=10)
                BS = json.loads(BS_r.content)       
        
                for year in IS:
                    y = year['date']
                    dates.append(y)
                
                for item in range(len(dates)):
                    IS_financials[dates[item]] = {}
                    IS_financials[dates[item]]['Revenue'] = IS[item]['revenue'] / thousands
                    IS_financials[dates[item]]["Cost of Revenue"] = IS[item]['costOfRevenue'] / thousands
                    IS_fundementals = pd.DataFrame.from_dict(IS_financials, orient="columns")
    
                for item in range(len(dates)):
                    BS_financials[dates[item]] = {}
                    BS_financials[dates[item]]['Cash and Equivalents'] = BS[item]['cashAndCashEquivalents'] / thousands
                    BS_financials[dates[item]]['Short Term Investments'] = BS[item]['shortTermInvestments'] / thousands
                    BS_fundementals = pd.DataFrame.from_dict(BS_financials, orient="columns")
                    
    
            except Exception as e:
                apiList = "Error..."
    
            return render(request, 'financials.html', {'IS': IS_fundementals.to_html(), 'BS': BS_fundementals.to_html()})
        else:
            return render(request, 'financials.html', {})
    

    【讨论】:

    • 谢谢。我能问一下合理的超时时间是什么吗?
    • 如果外部api宕机或者非常非常慢,可以及时发现反馈。
    猜你喜欢
    • 2023-04-09
    • 2016-11-02
    • 1970-01-01
    • 2020-12-18
    • 2018-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-02
    相关资源
    最近更新 更多