LaM*_*Mut 4 python-2.7 wagtail
这是我的model.py文件
...
class LinkFields(models.Model):
link_external = models.URLField(
"External link",
blank=True,
null=True,
help_text='Set an external link if you want to describe the event from an other web site',
)
link_page = models.ForeignKey(
'wagtailcore.Page',
null=True,
on_delete=models.SET_NULL,
blank=True,
related_name='+',
help_text='Choose an existing page (event must have already been created)',
)
@property
def link(self):
if self.link_page:
return self.link_page.url
else:
return self.link_external
panels = [
FieldPanel('link_external'),
PageChooserPanel('link_page'),
]
class Meta:
abstract = True
class RelatedLink(LinkFields):
title = models.CharField(max_length=255, help_text="Link title")
panels = [
FieldPanel('title'),
MultiFieldPanel(LinkFields.panels, "Link"),
]
class Meta:
abstract = True
class HomePage(Page):
body = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel('body', classname="full"),
InlinePanel('related_links', label="Related events"),
]
class EventsPage(Page):
# Database fields
date = models.DateField("Event date")
topicTag = models.CharField(max_length = 25)
name = models.CharField(max_length = 50)
city = models.CharField(max_length = 20, default="Where it is")
place = models.CharField(max_length = 20, blank=True)
body = RichTextField(blank=True)
# Search index configuration
search_fields = Page.search_fields + (
index.SearchField('topicTag'),
index.SearchField('place'),
index.FilterField('date'),
)
# Editor panels configuration
content_panels = Page.content_panels + [
FieldPanel('date'),
FieldPanel('topicTag'),
FieldPanel('name', classname="title"),
FieldPanel('city'),
FieldPanel('place'),
FieldPanel('body'),
]
class EventsRelatedLink(Orderable, RelatedLink):
page = ParentalKey('HomePage', related_name='related_links')
Run Code Online (Sandbox Code Playgroud)
EventsPages是HomePage的子页面,它本身显示后续子页面的链接。我的问题是我要显示在主页上的每个子页面的链接,我想访问所谓子页面的属性以显示一种预览。
这是我的home_page.html模板:
{% extends "base.html" %}
{% load wagtailcore_tags %}
{% block body_class %}template-homepage{% endblock %}
{% block content %}
<h1>THE <span class="pink">OPEN SOURCE</span> INNOVATION SPRING</h1>
<div class="intro">{{ page.body|richtext }}</div>
{% if page.related_links.all %}
<ul>
{% for item in page.related_links.all %}
<li><a href="{{ item.link }}">{{ item.title }}</a></li>
<br><div class="description">{{ item.date }}
<span class="pink">[{{ item.topicTag }}]</span>
{{ item.name }} <span class="pink">[{{ item.city }}]</span>
</div>
{% endfor %}
</ul>
{% endif %}
{% endblock %}
Run Code Online (Sandbox Code Playgroud)
当然,所有带*作为EventsPage Model属性的“ item。*”都不起作用。我很确定自己输入的方式有误,但是请寻求帮助。
首先,{{ item.date }}由于item是RelatedLink对象而不是页面对象,因此无法使用。要访问页面对象,您将需要{{ item.link_page.date }}(当然,以及当编辑器提供link_external代替时的一些替代行为link_page)。但是,此更改本身是不够的-它适用于核心页面属性(例如)item.link_page.title,但不适用于特定于事件的属性(例如)date。
发生这种情况的原因有一个解释:每当您通过EventPage.objects.all(),或page.get_children()或(在这种情况下)之类的操作检索一组页面时,page.related_links通常所有结果都是同一类型。如果它是有可能涵盖多种不同类型的页面的操作(例如- EventPage.objects.all()永远只能返回赛事页面的对象,但page.get_children()还是page.related_links可以返回任何类型的页面),那么为了保持它们都是一样的,它必须返回他们的“最低公分母”-所有页面类型所属的基本页面模型。这提供了title所有页面都通用的字段,但没有特殊用途的字段。
(这是数据库查找工作方式的限制-如果我们想以其最特定的形式获取每个页面对象,则数据库查询将必须立即检查所有与页面相关的表,这效率非常低。)
考虑到这一点,有几个选项可供您选择:
首先,如果您知道您网站上的编辑者只会选择EventPages作为相关链接-并且基于您的help_text和您正在编写类似{{ item.date }}且{{ item.city }}可能不会这样做的事实,这似乎是一个安全的假设对于其他类型的页面没有意义-然后您可以通过将外键指向以下位置来在数据库级别实施此操作EventPage:
link_page = models.ForeignKey(
'myapp.EventPage', # replace 'myapp' with your application name
null=True,
on_delete=models.SET_NULL,
blank=True,
related_name='+',
help_text='Choose an existing page (event must have already been created)',
)
Run Code Online (Sandbox Code Playgroud)
进行此更改后,Wagtail管理员中的页面选择器将只允许您EventPage为此字段选择s,并且item.link_page将为您提供完整的EventPage对象,从而使您可以编写{{ item.link_page.date }}。
其次:如果您需要在相关链接中支持其他页面类型-例如,也许您的NewsPage模型也具有一个date字段,并且还希望能够选择这些页面作为相关链接-那么您可以将基本Page对象转换为通过调用更具体的页面类型.specific。例如:{{ item.link_page.specific.date }}。缺点是.specific每次使用时都会执行额外的数据库查找,这可能会损害性能。作为简单的优化,您可以使用{% with %}标签将其分配给变量:
{% for item in page.related_links.all %}
{% with item.link_page.specific as related_page %}
<li><a href="{{ item.link }}">{{ item.title }}</a></li>
<br><div class="description">{{ related_page.date }}
<span class="pink">[{{ related_page.topicTag }}]</span>
{{ related_page.name }} <span class="pink">[{{ related_page.city }}]</span>
</div>
{% endwith %}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)