如何从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 %}
关键注意事项
- API调用优化:必须添加缓存逻辑,避免每次请求都调用天气API,既节省资源又提升页面加载速度。
- 异常处理:捕获API请求可能出现的错误(比如网络超时、接口返回异常),防止天气服务故障导致整个首页无法正常显示。
- 避免在模型其他方法中调用API:不要在
save或后台字段处理方法中调用API,否则会导致CMS后台保存页面时卡顿甚至报错。
关于之前方案失败的原因分析
- 方案1:单独编写视图函数会绕过Wagtail的页面上下文机制,无法自动获取CMS填充的首页字段数据,导致原有内容丢失。
- 方案2:直接在模型中添加API调用函数,可能是因为调用时机错误(比如在后台保存时触发而非页面访问时)、未正确获取关联的
CardLocation数据,或者缺少异常处理导致报错。
内容的提问来源于stack exchange,提问作者Blerdijan
相关产品推荐
相关产品推荐

