You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 19:09:33