如何在Django中正确向前端传递JSON数据并解决路由问题?
问题与解决方案
问题描述
- JSON返回格式异常:从第三方API获取JSON数据后,通过
JsonResponse返回时,前端收到的是包含JSON内容的HTML页面,无法直接用JavaScript解析。 - 路由冲突与模板调用问题:
ShowProjectBudgetList类视图和json_project_budget视图函数的路由路径重复(均为/customer/),需调整路由并实现模板中调用该JSON接口。
相关代码
views.py(JSON接口视图)
def json_project_budget(request): session = requests_cache.CachedSession('project_budget_cache') url = config('REPORT_PROJECT_BUDGET') response = session.get(url=url, auth=UNICA_AUTH).json() queryset = [] for item in response: my_js = json.dumps(item) parsed_json = ReportProjectBudgetSerializer.parse_raw(my_js) for budget in parsed_json.BudgetData: budget.SectionGUID = CleanSections.objects.get(GUID=budget.SectionGUID) budget.СompletedContract = budget.СompletedContract * 100 budget.СompletedEstimate = budget.СompletedEstimate * 100 queryset.append(budget) return JsonResponse(response, safe=False)
views.py(模板渲染视图)
class ShowProjectBudgetList(ListView): login_url = '/login/' redirect_field_name = '' template_name = 'customer/customer_home.html' context_object_name = 'json_list' allow_empty = True def get_queryset(self): return None
urls.py
path('customer/', ShowProjectBudgetList.as_view(), name='customer_view'), path('customer/', json_project_budget, name='json_project_budget'),
解决方案
一、修复JsonResponse返回格式问题
你当前返回的是第三方API的原始响应,但实际处理后的queryset是模型对象列表,直接返回会导致序列化异常,且需明确指定响应类型确保返回纯JSON:
修改json_project_budget视图:
def json_project_budget(request): session = requests_cache.CachedSession('project_budget_cache') url = config('REPORT_PROJECT_BUDGET') response = session.get(url=url, auth=UNICA_AUTH).json() queryset = [] for item in response: my_js = json.dumps(item) parsed_json = ReportProjectBudgetSerializer.parse_raw(my_js) for budget in parsed_json.BudgetData: # 注意:模型对象无法直接序列化,需提取具体字段(例如name) section = CleanSections.objects.get(GUID=budget.SectionGUID) budget.SectionGUID = section.name budget.СompletedContract = budget.СompletedContract * 100 budget.СompletedEstimate = budget.СompletedEstimate * 100 # 将Pydantic模型转成字典(若为Django模型可使用model_to_dict) queryset.append(budget.dict()) # 返回处理后的数据集,并明确指定JSON类型 return JsonResponse(queryset, safe=False, content_type='application/json')
关键说明:
- 模型对象不能直接被
JsonResponse序列化,需转换为字典格式; - 指定
content_type='application/json'确保响应头正确,避免浏览器将其识别为HTML; - 返回处理后的
queryset而非原始第三方API响应,保证前端拿到的是你加工后的数据。
二、解决路由冲突与模板调用问题
- 调整路由,避免路径重复
修改urls.py,给JSON接口分配独立路径:
path('customer/', ShowProjectBudgetList.as_view(), name='customer_view'), path('customer/budget-data/', json_project_budget, name='json_project_budget'),
- 在模板中调用JSON接口
在customer/customer_home.html中使用JavaScript的fetch请求接口并解析数据:
<script> document.addEventListener('DOMContentLoaded', function() { // 使用Django模板标签生成接口路径,避免硬编码 fetch("{% url 'json_project_budget' %}") .then(response => { if (!response.ok) throw new Error('请求失败'); return response.json(); }) .then(data => { // 这里处理解析后的JSON数据,示例:生成表格 const container = document.getElementById('budget-container'); const table = document.createElement('table'); data.forEach(item => { const row = table.insertRow(); row.insertCell().textContent = item.SectionGUID; row.insertCell().textContent = `${item.СompletedContract}%`; row.insertCell().textContent = `${item.СompletedEstimate}%`; }); container.appendChild(table); }) .catch(err => console.error('获取数据出错:', err)); }); </script> <!-- 数据展示容器 --> <div id="budget-container"></div>
关键说明:
- 用
{% url 'json_project_budget' %}模板标签自动生成接口路径,适配不同部署环境; - 通过
response.json()直接解析JSON数据,无需处理HTML内容。
内容的提问来源于stack exchange,提问作者Kirill_N
相关产品推荐
相关产品推荐

