我有一个 Django/Wagtail 项目。
我修改了 models.py 中的主页,然后在 Wagtail CMS 中填充了主页新创建的字段。
这是我的 models.py 的样子:
from django.db import models
from wagtail.core.models import Page
from wagtail.admin.edit_handlers import FieldPanel, InlinePanel, MultiFieldPanel
from wagtail.core.fields import RichTextField
from modelcluster.fields import ParentalKey
from modelcluster.models import ClusterableModel
from wagtail.core.models import Orderable
from wagtail.images.edit_handlers import ImageChooserPanel
from django.shortcuts import render
class HomePage(Page):
templates = "templates/home/home_page.html"
background_image = models.ForeignKey(
'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+'
)
hero_title = models.CharField(max_length=255, blank=True, null=True)
form_placeholder_text = models.CharField(max_length=255, blank=True, null=True)
form_cta_button_text = models.CharField(max_length=255, blank=True, null=True)
hero_title_2 = models.CharField(max_length=255, blank=True, null=True)
hero_title_3 = models.CharField(max_length=255, blank=True, null=True)
description = RichTextField(blank=True, null=True)
hero_title_4 = models.CharField(max_length=255, blank=True, null=True)
content_panels = Page.content_panels + [
MultiFieldPanel([
ImageChooserPanel('background_image'),
FieldPanel('hero_title'),
FieldPanel('form_placeholder_text'),
FieldPanel('form_cta_button_text'),
InlinePanel('slider_items', label="Slider Items"),
], heading="Hero Section 1"),
MultiFieldPanel([
FieldPanel('hero_title_2'),
InlinePanel('card_locations', label="Card Locations"),
], heading="Hero Section 2"),
MultiFieldPanel([
FieldPanel('hero_title_3'),
FieldPanel('description'),
], heading="Hero Section 3"),
MultiFieldPanel([
FieldPanel('hero_title_4'),
InlinePanel('column_one_items', label="Column One Items"),
InlinePanel('column_two_items', label="Column Two Items"),
InlinePanel('column_three_items', label="Column Three Items"),
], heading="Hero Section 4"),
]
class SliderItem(Orderable):
page = ParentalKey(HomePage, on_delete=models.CASCADE, related_name='slider_items')
slider_text = models.CharField(max_length=255, blank=True, null=True)
slider_link = models.URLField(blank=True, null=True)
panels = [
FieldPanel('slider_text'),
FieldPanel('slider_link'),
]
class CardLocation(Orderable):
page = ParentalKey(HomePage, on_delete=models.CASCADE, related_name='card_locations')
card_location_text = models.CharField(max_length=255, blank=True, null=True)
card_location_link = models.URLField(blank=True, null=True)
panels = [
FieldPanel('card_location_text'),
FieldPanel('card_location_link'),
]
class ColumnOneItem(Orderable):
page = ParentalKey(HomePage, on_delete=models.CASCADE, related_name='column_one_items')
column_one_title = models.CharField(max_length=255, blank=True, null=True)
column_one_link = models.URLField(blank=True, null=True)
panels = [
FieldPanel('column_one_title'),
FieldPanel('column_one_link'),
]
class ColumnTwoItem(Orderable):
page = ParentalKey(HomePage, on_delete=models.CASCADE, related_name='column_two_items')
column_two_title = models.CharField(max_length=255, blank=True, null=True)
column_two_link = models.URLField(blank=True, null=True)
panels = [
FieldPanel('column_two_title'),
FieldPanel('column_two_link'),
]
class ColumnThreeItem(Orderable):
page = ParentalKey(HomePage, on_delete=models.CASCADE, related_name='column_three_items')
column_three_title = models.CharField(max_length=255, blank=True, null=True)
column_three_link = models.URLField(blank=True, null=True)
panels = [
FieldPanel('column_three_title'),
FieldPanel('column_three_link'),
]
现在,在views.py 中,我创建了一个函数,该函数调用天气API 并返回该位置的温度(我将其作为参数传递)。这是函数:
def get_today_weather(location):
"""
Fetch the weather data for the current day for a given location.
"""
url = f"{BASE_URL}/{location}/today?unitGroup=metric&key={API_KEY}&contentType=json"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
return data["currentConditions"]["temp"]
else:
return None # Return None if there's an error
现在,我的目标是,当我访问我的主页 www.example.com 时,我希望显示我通过 Wagtail CMS(可订购)插入的所有位置的温度。
因此,如果我想获取新位置的数据,我只需转到 Wagtail CMS 并在我的 Orderable 中添加一个新位置即可。
我尝试了很多方法:
我尝试在views.py中创建一个函数来获取Orderable的值,然后调用get_today_weather函数,最后在我的home_page.html中渲染这些值。这里的问题是,当我访问我的主页 www.example.com 时,它会呈现一个全新的模板,而不是我的主页(我已使用 Wagtail 管理 CSM 字段中的数据填充该主页)。这里,数据是从 API 显示的,但不幸的是,我创建的其他字段消失了。
我尝试在 models.py 中为我的模型创建一个函数,它将调用 get_today_weath 函数,然后将数据传递到我的主页,但没有成功。
有人可以建议我解决这个问题吗?
在主页模型上定义 a
get_context
方法。这可用于将您想要的任何其他变量添加到模板上下文中,因此您可以根据从页面的 weather_reports
关系检索到的位置创建一个 card_locations
列表:
class HomePage(Page):
# ...
def get_context(self, request, *args, **kwargs):
context = super().get_context(request, *args, **kwargs)
context["weather_reports"] = [
{
"location": card.card_location_text,
"weather": get_today_weather(card.card_location_text)
}
for card in self.card_locations.all()
]
return context
然后,在您的模板中:
<ul>
{% for report in weather_report %}
<li>{{ location }}: {{ weather }}</li>
{% endfor %}
</ul>
这是我解决问题的方法:
首先我将views.py中的get_today_weather函数转换为models.py中的主页。
class HomePage(Page):
templates = "templates/home/home_page.html"
background_image = models.ForeignKey(
'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+'
)
hero_title = models.CharField(max_length=255, blank=True, null=True)
form_placeholder_text = models.CharField(max_length=255, blank=True, null=True)
form_cta_button_text = models.CharField(max_length=255, blank=True, null=True)
hero_title_2 = models.CharField(max_length=255, blank=True, null=True)
hero_title_3 = models.CharField(max_length=255, blank=True, null=True)
description = RichTextField(blank=True, null=True)
hero_title_4 = models.CharField(max_length=255, blank=True, null=True)
content_panels = Page.content_panels + [
MultiFieldPanel([
ImageChooserPanel('background_image'),
FieldPanel('hero_title'),
FieldPanel('form_placeholder_text'),
FieldPanel('form_cta_button_text'),
InlinePanel('slider_items', label="Slider Items"),
], heading="Hero Section 1"),
MultiFieldPanel([
FieldPanel('hero_title_2'),
InlinePanel('card_locations', label="Card Locations"),
], heading="Hero Section 2"),
MultiFieldPanel([
FieldPanel('hero_title_3'),
FieldPanel('description'),
], heading="Hero Section 3"),
MultiFieldPanel([
FieldPanel('hero_title_4'),
InlinePanel('column_one_items', label="Column One Items"),
InlinePanel('column_two_items', label="Column Two Items"),
InlinePanel('column_three_items', label="Column Three Items"),
], heading="Hero Section 4"),
]
def get_today_weather(self, location):
"""
Fetch the weather data for the current day for a given location.
"""
url = f"{BASE_URL}/{location}/today?unitGroup=metric&key={API_KEY}&contentType=json"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
return data["currentConditions"]["temp"]
else:
return None # Return None if there's an error
def get_all_weather_data(self):
weather_data = []
for card_location in self.card_locations.all():
location_weather = self.get_today_weather(card_location.card_location_text)
if location_weather is not None:
weather_data.append({
'location': card_location.card_location_text,
'temperature': location_weather
})
return weather_data
然后我就可以在 HTML 中呈现信息了:
{% for weather in page.get_all_weather_data %}
<div class="single-weather">
<a href="#">
<span class="weather-box">
<div class="weather-img">
<div class="cloud cloud1">
<img src="{% static 'img/Cloud1.png' %}" alt="">
</div>
<div class="sun cloud3">
<img src="{% static 'img/sun.png' %}" alt="">
</div>
</div>
<div class="weather-containt">
<h3>{{ weather.location }}
<span>
<!-- Access the weather data for the current card location -->
{{ weather.temperature }}°C
</span>
</h3>
<h4>Oblacno</h4>
<p>Vjetar: 13km/h 236</p>
<p>Vlaznost: 65% </p>
</div>
</span>
</a>
</div>
{% endfor %}