如何在Django views中调用API并将数据渲染到HTML模板
问题原因及修复方案
你现在没有报错大概率是因为没有对API请求加异常捕获和状态校验,非200响应、请求超时、JSON解析失败这类问题都不会主动抛出,自然看不到错误提示。按下面步骤排查修改即可:
1. 优先修复同项目API调用的坑
如果你调用的http://127.0.0.1:1500/api/是当前Django项目自身提供的接口,不要用requests发起网络请求调用:Django默认runserver是单线程模式,当前视图请求已经占了唯一的工作线程,API请求会一直等待资源卡住,永远拿不到返回。直接把API接口对应的业务逻辑封装成独立函数,在视图里直接调用这个函数拿数据即可,性能和稳定性都高很多。
如果是外部服务的API,就按下面的代码加校验和异常捕获:
2. 修正views.py代码,加错误校验
import requests from django.shortcuts import render from .models import Userbase def homeview(request): # 先初始化table_data为空列表,避免接口异常导致模板报错 table_data = [] try: # 加超时参数,避免请求无限卡住,timeout单位是秒 resp = requests.get('http://127.0.0.1:1500/api/', timeout=5) # 先判断请求是否成功,状态码非200直接抛异常 resp.raise_for_status() # 开发阶段可以打开下面的注释,打印返回内容确认结构是否符合预期 # print("API返回内容:", resp.text) api_result = resp.json() # 注意:如果你的接口返回的是嵌套结构,比如{"code":200,"data": [xxx]},要取对应层级的列表,比如table_data = api_result.get("data", []) table_data = api_result except requests.exceptions.RequestException as e: # 打印错误信息,开发阶段可以直接看到问题 print("API请求异常:", str(e)) if request.method == 'POST': userb = Userbase() userb.company_code = request.POST.get('company_code') userb.Area = request.POST.get('area') userb.country = request.POST.get('country') userb.From_Date = request.POST.get('from_Date') userb.To_Date = request.POST.get('to_Date') userb.Predicted_Paid_days = request.POST.get('Predicted_Paid_days') userb.PBK_Desc = request.POST.get('PBK_Desc') userb.Vendor_Name = request.POST.get('Vendor_Name') userb.Reference = request.POST.get('Reference') userb.Payment_Term = request.POST.get('Payment_Term') userb.save() # 这里之前的userbase是save之前查的,数据是旧的,要重新查一次 userbase = Userbase.objects.all() return render(request, 'home.html', {'userbase':userbase, 'table_data':table_data}) userbase = Userbase.objects.all() return render(request, 'home.html', {'table_data':table_data, 'userbase': userbase})
3. 模板兼容处理
如果API返回的数据结构和你预期的不一致,可以在模板里加空判断,避免无数据时页面空白:
<table class="table" id='table_id'> <thead id="tablehead"> <tr> <th>Stage</th> <th>Region</th> <th>Area</th> </tr> </thead> <tbody> {% if table_data %} {% for item in table_data %} <tr> <td>{{ item.stage }}</td> <td>{{ item.region }}</td> <td>{{ item.area }}</td> </tr> {% endfor %} {% else %} <tr> <td colspan="3">暂无数据</td> </tr> {% endif %} </tbody> </table>
修改后重启服务,看控制台打印的错误信息就能定位具体问题,要么是API不通、要么是返回的JSON结构和你遍历的逻辑不匹配,对应调整即可。
内容的提问来源于stack exchange,提问作者imran_44
相关产品推荐
相关产品推荐

