如何在可排序的代码段中获取类别值

时间:2019-08-15 20:50:13

标签: wagtail

我正在尝试创建一个可路由的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

我可以在后端创建资源,而可排序的代码段也可以运行,并且可以看到多种资源类别。如何使用摘要使用过滤器和类别?

1 个答案:

答案 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上还有一个非常相关的视频(但是您可以将其用于参考资料,而不是博客作者)

当然总会有Wagtail Docs (Inline Models/Orderables)