从Django视图中的API调用呈现多个数据帧

2024-09-29 23:17:04 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我的第一次尝试是在“if request.method=='POST'”块中的try块中,尝试一个接一个地执行所有request.get和jsons.load调用。当只从一个API调用中获取数据时,这种方法效果很好,但在5个API调用中不起作用。我会在assigned error之前获取引用的局部变量,这使我认为是multiple requests.get或json.loads造成了错误

我当前的尝试(是出于好奇而创建的,以查看它是否以这种方式工作)确实按照预期工作,但obv不正确,因为它在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创建单独的函数,但这样我就无法在同一页上呈现它们。我可以使用嵌套函数吗?其中只有主函数呈现给模板,而所有内部函数只是将数据帧返回给外部函数?基于类的视图对于这样的东西会更好吗?我从未使用过基于类的视图,因此这将是一个学习曲线

我的另一个问题是如何更改从dataframe呈现的表中的html?当前呈现的表格/字体相当大

谢谢你的提示/建议


Tags: 数据函数apijsonforgetbsis
1条回答
网友
1楼 · 发布于 2024-09-29 23:17:04

只在.to_html()方法中使用pandas是不常见的,但我在django方法中调用pandas的时间更短。 更常见的方法是使用django template的循环方法在ISBS对象上循环以生成html表

为了使此方法更有效,请将BSapi调用移出日期循环,只要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', {})

相关问题 更多 >

    热门问题