Django中API请求结果无法渲染至HTML模板的问题排查
问题分析与解决方案
相关代码
调用Google Finance API获取新闻的视图函数(someapp/views.py):
def news(request): if request.method == 'POST': url = "https://google-finance4.p.rapidapi.com/ticker/" querystring = {"t":"ETH-USD","hl":"en","gl":"US"} headers = { "X-RapidAPI-Key": "API KEY", "X-RapidAPI-Host": "google-finance4.p.rapidapi.com" } response = requests.request("GET", url, headers=headers, params=querystring) response.status_code response.text response.json() articles = response.json()['news'] return render(request, 'news.html', { "article": articles }) else: return HttpResponse('Error')
渲染页面代码(news.html):
<body class="bg-dark"> <div style=" position: flex; width: 450px; align-items: center; align-content: center; justify-content: center; margin: 370px auto; " > <img class ="img-fluid" src="{% load static %} /static/logo.png" " alt="Crypto Talk" </div> <p>**{{ article }}**</p> </body>
发起POST请求的页面代码:
<form class="form-inline" method="POST" action="{{ 'news/' }}" name="news" > <div class="input-group mb-3" style="margin: 0 auto; display: flex; width: 450px" > {%csrf_token%} <input type="text" class="form-control" placeholder="Enter Crypto" name="search" style=" display: block; margin: 0 auto; border-top-left-radius: 0; border-bottom-right-radius: 0; border-top-left-radius: 5px; border-bottom-left-radius: 5px; " /> <button class="btn btn-outline-primary btn-md" type="submit" id="button-addon2" > Search </button>
问题描述
提交POST请求后跳转到news.html,但页面仅显示logo,API返回的文章内容未渲染,终端出现"Not Found: /news/requestProvider.js.map"错误。需要排查是Django模板语法还是视图逻辑的问题,并将API返回的news字段中的文章以类似谷歌搜索的样式渲染出来。
问题排查与修复
1. 模板语法错误(核心问题)
- img标签语法错误:
{% load static %}需单独作为一行代码,不能嵌套在src属性内,且img标签未闭合。修改为:{% load static %} <img class="img-fluid" src="{% static 'logo.png' %}" alt="Crypto Talk" /> - 文章渲染错误:
**{{ article }}**是Markdown语法,Django模板不会自动解析;且article是列表对象,直接输出只会显示字符串形式的列表。需用{% for %}循环遍历每个文章项,提取标题、链接、摘要等字段。
2. 视图逻辑问题
- 未使用用户输入的加密货币参数:当前querystring里的
t固定为ETH-USD,未获取POST提交的search参数。需从request.POST中获取参数并替换:crypto_ticker = request.POST.get('search', 'ETH-USD') querystring = {"t": crypto_ticker, "hl": "en", "gl": "US"} - 重复调用response.json():多次调用会重复解析响应,建议存为变量复用:
response_data = response.json() articles = response_data.get('news', []) # 用get避免KeyError - else分支返回不友好:当前GET请求返回
HttpResponse('Error'),应返回包含搜索表单的页面,而非错误文本。
3. 表单action错误
action="{{ 'news/' }}"写法错误,应使用Django的URL反转(需先在urls.py中给news视图命名):
<form class="form-inline" method="POST" action="{% url 'news' %}" name="news" >
4. requestProvider.js.map错误
该错误是浏览器尝试加载前端JS文件的source map,与Django逻辑无关,不影响功能。可忽略,或检查页面中引入的JS文件是否包含source map引用,若不需要可移除相关注释。
修改后的完整代码
views.py
import requests from django.shortcuts import render from django.http import HttpResponse def news(request): if request.method == 'POST': url = "https://google-finance4.p.rapidapi.com/ticker/" # 获取用户提交的加密货币代码,默认ETH-USD crypto_ticker = request.POST.get('search', 'ETH-USD') querystring = {"t": crypto_ticker, "hl": "en", "gl": "US"} headers = { "X-RapidAPI-Key": "API KEY", # 替换为你的RapidAPI密钥 "X-RapidAPI-Host": "google-finance4.p.rapidapi.com" } try: response = requests.get(url, headers=headers, params=querystring) response.raise_for_status() # 抛出HTTP错误 response_data = response.json() articles = response_data.get('news', []) except Exception as e: articles = [] # 可添加日志记录错误 return render(request, 'news.html', { "articles": articles, "selected_ticker": crypto_ticker }) else: # GET请求返回搜索表单页面 return render(request, 'search.html')
news.html(谷歌搜索样式渲染)
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Crypto News</title> <style> .bg-dark { background-color: #121212; color: white; min-height: 100vh; padding: 20px; } .search-bar { max-width: 600px; margin: 20px auto; } .news-card { max-width: 600px; margin: 10px auto; padding: 15px; background-color: #1e1e1e; border-radius: 8px; text-decoration: none; color: white; display: block; transition: background-color 0.2s; } .news-card:hover { background-color: #2d2d2d; color: white; } .news-title { font-size: 18px; margin-bottom: 5px; color: #8ab4f8; } .news-snippet { font-size: 14px; color: #9aa0a6; margin-bottom: 8px; } .news-source { font-size: 12px; color: #dadce0; } </style> </head> <body class="bg-dark"> <!-- 返回搜索表单的链接 --> <div class="search-bar"> <form method="POST" action="{% url 'news' %}"> {% csrf_token %} <div class="input-group mb-3"> <input type="text" class="form-control" placeholder="Enter Crypto (e.g., BTC-USD)" name="search" value="{{ selected_ticker }}"> <button class="btn btn-outline-primary" type="submit">Search</button> </div> </form> </div> <!-- 渲染新闻列表 --> {% if articles %} {% for item in articles %} <a href="{{ item.link }}" target="_blank" class="news-card"> <h3 class="news-title">{{ item.title }}</h3> {% if item.snippet %} <p class="news-snippet">{{ item.snippet }}</p> {% endif %} <p class="news-source">{{ item.source }} • {{ item.time_ago }}</p> </a> {% endfor %} {% else %} <div style="text-align: center; margin-top: 50px;"> <p>No news found for {{ selected_ticker }}</p> </div> {% endif %} </body> </html>
search.html(搜索表单页面)
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Crypto Talk</title> <style> .bg-dark { background-color: #121212; color: white; min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; } .logo { margin-bottom: 30px; } .search-form { width: 450px; } </style> </head> <body class="bg-dark"> <img class="img-fluid logo" src="{% static 'logo.png' %}" alt="Crypto Talk" /> <form class="form-inline search-form" method="POST" action="{% url 'news' %}"> {% csrf_token %} <div class="input-group mb-3"> <input type="text" class="form-control" placeholder="Enter Crypto (e.g., BTC-USD)" name="search"> <button class="btn btn-outline-primary btn-md" type="submit" id="button-addon2">Search</button> </div> </form> </body> </html>
urls.py(需添加命名URL)
from django.urls import path from . import views urlpatterns = [ path('news/', views.news, name='news'), # 根路径指向搜索页面 path('', views.news, name='home'), ]
内容的提问来源于stack exchange,提问作者drafty
相关产品推荐
相关产品推荐

