Django:如何从HTML模板返回JSON对象至views.py
解决方法
你完全不需要把模板里生成的JSON传回views——这个思路绕远了,直接在views里把查询到的数据转换成JSON格式返回,就能让外部通过GET请求直接获取JSON数据,比通过模板中转高效得多。
方案1:直接返回JSON响应
修改views.py,跳过模板,直接把查询集序列化为JSON返回:
from django.http import JsonResponse from django.db.models import OuterRef, Subquery def test_json(request): n = 10 # 修正原代码笔误:youngest_peoples 改为 youngest_people youngest_people = Persons.objects.filter( country=OuterRef('country') ).order_by('age')[:n] queryset = Persons.objects.filter( id__in=Subquery(youngest_people.values('id')) # 修正过滤逻辑,确保用id匹配 ).order_by('country', '-age') # 将查询集转换为可序列化的字典列表 persons_data = [] for person in queryset: persons_data.append({ "name": person.name, "weight": person.weight, "height": person.height, "date of birth": person.dob.strftime('%Y-%m-%d') # 格式化日期为字符串,避免序列化错误 }) # 返回JSON响应 return JsonResponse({"data": persons_data})
此时外部直接GET请求这个视图的URL,就能拿到结构正确的JSON数据。
方案2:同时支持HTML页面和JSON接口
如果既需要展示HTML页面,又要提供JSON接口,可以在同一个视图里根据请求参数判断返回内容:
from django.http import JsonResponse from django.shortcuts import render from django.db.models import OuterRef, Subquery def test(request): n = 10 youngest_people = Persons.objects.filter( country=OuterRef('country') ).order_by('age')[:n] queryset = Persons.objects.filter( id__in=Subquery(youngest_people.values('id')) ).order_by('country', '-age') # 如果请求参数包含format=json,返回JSON if request.GET.get('format') == 'json': persons_data = [] for person in queryset: persons_data.append({ "name": person.name, "weight": person.weight, "height": person.height, "date of birth": person.dob.strftime('%Y-%m-%d') }) return JsonResponse({"data": persons_data}) # 否则返回HTML页面 else: context = {'persons': queryset} return render(request, 'test.html', context)
这样访问/test/返回HTML页面,访问/test/?format=json就能获取JSON数据。
原模板的小问题(可选修复)
如果要保留原HTML页面的展示,需要修复模板里循环最后多一个逗号的问题,否则生成的JSON会格式错误:
<script> var jsonObject = { "data": [ {% for person in persons %} { "name": "{{ person.name }}", "weight": {{ person.weight }}, "height": {{ person.height }}, "date of birth": "{{ person.dob }}" }{% if not forloop.last %},{% endif %} <!-- 添加判断,避免最后一个元素后多逗号 --> {% endfor %} ] }; </script>
内容的提问来源于stack exchange,提问作者user21950663
相关产品推荐
相关产品推荐

