我正在尝试创建一个可路由的w形页面,该页面按类别过滤摘要。片段可以具有多个类别。我不知道为什么当我尝试获取类别时,它们在我的页面上显示为“无”。
from django.db import models
from django.shortcuts import render
from modelcluster.models import ClusterableModel
from modelcluster.fields import ParentalKey
from wagtail.core.models import Page, Orderable
from wagtail.core.fields import RichTextField
from wagtail.admin.edit_handlers import (
FieldPanel,
PageChooserPanel,
MultiFieldPanel,
InlinePanel
)
from wagtail.images.edit_handlers import ImageChooserPanel
from wagtail.snippets.edit_handlers import SnippetChooserPanel
from wagtail.contrib.routable_page.models import RoutablePageMixin,
路线 从wagtail.snippets.models导入register_snippet 导入uuid
类Resource(ClusterableModel): “”“资源摘录”“”
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
resource_name = models.CharField(max_length=128, blank=False, null=True)
phone_number = models.CharField(max_length=12, blank=True, null=True)
website = models.URLField(blank=True, null=True)
info = RichTextField(blank=True, null=True)
panels = [
MultiFieldPanel(
[
FieldPanel("resource_name"),
FieldPanel("phone_number"),
],
heading="Resource information"
),
MultiFieldPanel(
[
FieldPanel('website')
],
heading="Links"
),
MultiFieldPanel(
[
FieldPanel('info')
],
heading="Info"
),
MultiFieldPanel(
[
InlinePanel("category")
]
)
]
def __str__(self):
"""String representation of this class"""
return self.resource_name
class Meta:
verbose_name = "Resource"
verbose_name_plural = "Resources"
register_snippet(Resource)
class ResourceCatsOrderable(Orderable):
"""child category for multiple category choices"""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
resource = ParentalKey('home.Resource', related_name="category")
category = models.ForeignKey('home.ResourceCategory', on_delete=models.CASCADE, null=True, blank=True)
panels = [
SnippetChooserPanel("category")
]
class ResourceCategory(models.Model):
"""Snippet for Resources category"""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
category_name = models.CharField(max_length=128, blank=False, null=True)
panels = [
MultiFieldPanel(
[
FieldPanel('category_name')
],
heading="Category"
)
]
def __str__(self):
"""String representation of this class"""
return self.category_name
class Meta:
verbose_name = "Category"
verbose_name_plural = "Categories"
register_snippet(ResourceCategory)
class HomePage(RoutablePageMixin, Page):
"""Home page model."""
template = "home/home_page.html"
max_count = 1
subtitle = models.CharField(max_length=100, blank=False, null=True)
left_col = RichTextField()
right_col = RichTextField()
content_panels = Page.content_panels + [
FieldPanel("subtitle"),
FieldPanel("left_col"),
FieldPanel("right_col")
]
class Meta:
verbose_name = "Home Page"
verbose_name_plural = "Home Pages"
@route(r'^resource/(?P<cat_slug>[-\w]+)/?$')
def resources_page(self, request, cat_slug, *args, **kwargs):
context = self.get_context(request, *args, **kwargs)
context['a_special_test'] = cat_slug
resources = Resource.objects.all()
print(resources)
context['resources'] = resources
return render(request, "home/resources_page.html", context)
我要测试的模板:
{% extends "base.html" %}
{% load static %}
{% load wagtailcore_tags wagtailimages_tags %}
{% block content %}
<div class="content">
<p>This is the resource page and it has this context {{a_special_test}}</p>
{% for resource in resources %}
<p>
<a href="{{ resource.website }}">
{{ resource.resource_name }}
</a>
</p>
<p>{{resource.category}}</p>
<p>{{resource.phone_number}}</p>
<div>{{resource.info | richtext}}</div>
{% endfor %}
</div>
在页面上我得到:
home.ResourceCatsOrderable.None
我可以在后端创建资源,而可排序的代码段也可以运行,并且可以看到多种资源类别。如何使用摘要使用过滤器和类别?
答案 0 :(得分:0)
我认为在将Django模型注册为代码段,ClusterableModels和Orderables之间存在一些困惑。
您几乎可以从[最终]从Django的Model
类继承的任何模型中创建代码段。
@register_snippet
class Category(models.Model):
"""Category for snippet."""
name = models.CharField(max_length=255)
# other fields
# add your panels and __str__
这是一个基本片段。它们可以变得像Django模型一样复杂。
尽管Orderable本质上是一种(简单的思考方式)Django InlineModel,但却采用了Wagtail方式。这里有些复杂的地方与这个答案无关,所以我现在就让它解决。
对于需要选择代码段的Orderable,它的外观应类似于以下几行:
class CategorySelectingOrderable(Orderable):
"""Category selecting orderable."""
page = ParentalKey("home.HomePage", related_name="resources")
category = models.ForeignKey("home.Category", on_delete=models.CASCADE)
panels = [
SnippetChooserPanel("category")
]
class Meta:
verbose_name = "Resource"
verbose_name_plural = "Resources"
def __str__(self):
return self.category.name
最后,在您的主页上,您将使用InlinePanel在Wagtail中创建重复的Orderable接口。
class HomePage(Page):
# Fields here
content_panels = Page.content_panels + [
MultiFieldPanel(
[
# Note that the first parameter is the same name as the related_name in the code block above
InlinePanel("resources", label="Resource", min_num=1)
],
heading="Author(s)",
),
]
在您的模板中,您可以使用以下方法遍历它们:
{% for resource in self.resources.all %}
{{ resource.category.name }}
{% endfor %}
我知道一开始可能需要很多代码,但是一旦执行几次,它就会成为第二自然。
我还有一个YouTube video on Orderables,并且在using a SnippetChooserPanel to Select Multiple Blog Authors上还有一个非常相关的视频(但是您可以将其用于参考资料,而不是博客作者)