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

如何从Wagtail Page的Orderable取值并调用API展示对应温度?

解决方案:通过Wagtail页面的get_context方法扩展上下文

核心思路

Wagtail的页面视图逻辑是基于Page模型的,不需要单独编写视图函数。重写HomePage模型的get_context方法,既能保留CMS填充的首页原有字段数据,又能将地点天气数据注入到模板上下文里。

步骤1:修改HomePage模型,重写get_context方法

在models.py的HomePage类中添加以下代码,结合你已有的get_today_weather函数处理天气数据:

from wagtail.models import Page, Orderable
from wagtail.admin.panels import InlinePanel
from django.core.cache import cache
# 导入你的get_today_weather函数
from .views import get_today_weather

# 假设你的CardLocation模型定义如下(如果已有可忽略)
class CardLocation(Orderable):
    page = ParentalKey('home.HomePage', related_name='card_locations')
    location_name = models.CharField(max_length=255)
    # 其他自定义字段(比如地址、排序权重等)

class HomePage(Page):
    # 你的现有首页字段定义...
    content_panels = Page.content_panels + [
        InlinePanel('card_locations', label='地点卡片'),
        # 其他CMS面板配置...
    ]

    def get_context(self, request, *args, **kwargs):
        # 先获取Wagtail默认的首页上下文(包含所有CMS填充的字段)
        context = super().get_context(request, *args, **kwargs)
        
        # 获取所有关联的CardLocation数据
        locations = self.card_locations.all()
        location_weather_list = []

        for loc in locations:
            # 用缓存减少API调用频率(示例缓存1小时)
            cache_key = f"weather_{loc.location_name}"
            weather_data = cache.get(cache_key)

            if not weather_data:
                try:
                    # 调用天气API获取数据
                    weather_data = get_today_weather(loc.location_name)
                    # 缓存结果,避免重复请求
                    cache.set(cache_key, weather_data, 3600)
                except Exception:
                    # API请求失败时的兜底处理
                    weather_data = {'temperature': '获取失败'}
            
            # 组合地点和天气数据
            location_weather_list.append({
                'location': loc,
                'temperature': weather_data.get('temperature')
            })
        
        # 将处理好的数据注入上下文
        context['location_weathers'] = location_weather_list
        return context

步骤2:在首页模板中渲染数据

在你的首页模板(比如home_page.html)中,通过上下文变量location_weathers遍历展示地点和温度:

{% for item in location_weathers %}
    <div class="location-card">
        <h3>{{ item.location.location_name }}</h3>
        <p>今日温度:{{ item.temperature }}</p>
        <!-- 渲染CardLocation的其他字段,比如地址、描述等 -->
    </div>
{% endfor %}

关键注意事项

  1. API调用优化:必须添加缓存逻辑,避免每次请求都调用天气API,既节省资源又提升页面加载速度。
  2. 异常处理:捕获API请求可能出现的错误(比如网络超时、接口返回异常),防止天气服务故障导致整个首页无法正常显示。
  3. 避免在模型其他方法中调用API:不要在save或后台字段处理方法中调用API,否则会导致CMS后台保存页面时卡顿甚至报错。

关于之前方案失败的原因分析

  • 方案1:单独编写视图函数会绕过Wagtail的页面上下文机制,无法自动获取CMS填充的首页字段数据,导致原有内容丢失。
  • 方案2:直接在模型中添加API调用函数,可能是因为调用时机错误(比如在后台保存时触发而非页面访问时)、未正确获取关联的CardLocation数据,或者缺少异常处理导致报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 18:45:13