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

Django网站加载慢:如何先加载空模板再异步填充热门股票数据?

解决方案:异步加载Django页面数据提升初始加载速度

嘿,作为Django新手碰到页面初始加载慢的问题太正常啦!你的核心需求是先让页面快速渲染出来,再异步填充股票数据,咱们一步步来实现这个方案~

1. 简化原视图,快速返回基础页面

原来的视图会同步请求多个第三方API,必须等所有请求完成才会返回页面,这就是加载慢的根源。现在咱们把这部分逻辑砍掉,让视图直接返回不带股票数据的页面:

from jinja2 import Environment, FileSystemLoader
from django.http import HttpResponse

def index(request):
    env = Environment(loader=FileSystemLoader('templates'))
    template = env.get_template('index.html')
    # 只传递空的股票列表,模板里要做好空数据的兼容处理
    template_values = {'popular_stocks': []}
    return HttpResponse(template.render(template_values))

2. 创建独立API视图,提供股票数据

接下来咱们写一个专门处理股票数据请求的视图,它只负责获取并返回JSON格式的股票数据,供前端异步调用:

from django.http import JsonResponse
from tools import fetcher
import requests
import json

def get_popular_stocks(request):
    popular = fetcher.get_tops()
    popular_stocks = []
    for instrument in popular:
        try:
            # 用f-string让代码更简洁
            r = requests.get(f'https://api.iextrading.com/1.0/stock/{instrument["symbol"]}/quote')
            r.raise_for_status()  # 捕获HTTP请求错误
            quote = json.loads(r.content.decode('utf-8'))
            popular_stocks.append(quote)
        except Exception as e:
            # 出错时可以记录日志,或者直接跳过该股票
            print(f"获取股票{instrument['symbol']}数据失败: {str(e)}")
            continue
    # safe=False是因为返回的是列表而非字典
    return JsonResponse(popular_stocks, safe=False)

3. 配置URL路由,让前端能访问API

在你的项目urls.py里添加新的路由,把刚才的API视图映射到一个可访问的URL:

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    # 新增API路由,前端会通过这个地址请求数据
    path('api/popular-stocks/', views.get_popular_stocks, name='popular-stocks-api'),
]

4. 修改前端模板,实现AJAX异步加载

最后在index.html里,先预留一个容器用来展示股票数据,再用JavaScript在页面加载完成后异步请求API并渲染数据。这里提供两种实现方式:

原生JavaScript版本(无需额外依赖)

<!-- 预留数据展示容器,先放加载提示 -->
<div id="popular-stocks-container">
    <p>正在加载热门股票数据...</p>
</div>

<script>
// 页面DOM加载完成后执行
document.addEventListener('DOMContentLoaded', function() {
    const container = document.getElementById('popular-stocks-container');
    
    // 发送异步请求
    fetch('/api/popular-stocks/')
        .then(response => {
            if (!response.ok) throw new Error('数据请求失败');
            return response.json();
        })
        .then(data => {
            // 清空加载提示
            container.innerHTML = '';
            
            if (data.length === 0) {
                container.innerHTML = '<p>暂无热门股票数据</p>';
                return;
            }
            
            // 动态生成股票列表HTML
            const stockList = document.createElement('ul');
            data.forEach(stock => {
                const listItem = document.createElement('li');
                // 格式化显示股票信息,涨跌百分比用正负号区分
                listItem.innerHTML = `<strong>${stock.symbol}</strong>: $${stock.latestPrice} 
                                      (${stock.changePercent > 0 ? '+' : ''}${stock.changePercent.toFixed(2)}%)`;
                stockList.appendChild(listItem);
            });
            container.appendChild(stockList);
        })
        .catch(error => {
            container.innerHTML = `<p>加载失败:${error.message}</p>`;
        });
});
</script>

jQuery版本(如果项目已引入jQuery)

<div id="popular-stocks-container">
    <p>正在加载热门股票数据...</p>
</div>

<script>
$(document).ready(function() {
    const $container = $('#popular-stocks-container');
    
    $.ajax({
        url: '/api/popular-stocks/',
        method: 'GET',
        dataType: 'json',
        success: function(data) {
            $container.empty();
            if (data.length === 0) {
                $container.html('<p>暂无热门股票数据</p>');
                return;
            }
            
            let $stockList = $('<ul></ul>');
            $.each(data, function(index, stock) {
                const changeSign = stock.changePercent > 0 ? '+' : '';
                const $listItem = $(`<li><strong>${stock.symbol}</strong>: $${stock.latestPrice} (${changeSign}${stock.changePercent.toFixed(2)}%)</li>`);
                $stockList.append($listItem);
            });
            $container.append($stockList);
        },
        error: function(xhr, status, error) {
            $container.html(`<p>加载失败:${error}</p>`);
        }
    });
});
</script>

额外优化建议

  • 缓存第三方API数据:股票数据不会实时高频变化,用Django缓存框架缓存API结果,比如缓存5分钟,避免重复请求第三方API:
    from django.core.cache import cache
    
    def get_popular_stocks(request):
        # 先从缓存取数据
        cached_data = cache.get('popular_stocks')
        if cached_data:
            return JsonResponse(cached_data, safe=False)
        
        # 原来的获取数据逻辑...
        
        # 缓存数据,过期时间300秒(5分钟)
        cache.set('popular_stocks', popular_stocks, 300)
        return JsonResponse(popular_stocks, safe=False)
    
  • 批量请求第三方API:如果fetcher.get_tops()返回大量股票符号,看看第三方API是否支持批量查询,一次请求多个股票数据,减少HTTP请求次数。

内容的提问来源于stack exchange,提问作者APorter1031

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:20:28