【问题标题】:passing tags to sidebar on wagtail将标签传递到鹡鸰的侧边栏
【发布时间】:2021-12-22 08:23:56
【问题描述】:

我希望将我的应用标签和类别传递到侧边栏。使用 RoutablePageMixin,用户可以从 detailPage 中的链接或侧边栏中显示具有给定值的所有标签/类别。

类别按预期通过,标签可以显示,但只能从 DetailPage 显示。 当我尝试访问 IndexPage/Sidebar 上的时,我收到一个错误:

Reverse for 'post_by_tag' with arguments '('',)' not found. 1 pattern(s) tried: ['tag/(?P<tag>[-\\w]+)/$'] 

...我很难找到原因,因为当人们从 detail_page 检索信息时,post_by_tag 效果很好。

我从头开始尝试并重试,但仍然处于第一阶段。我非常感谢任何可以帮助我的代码将标签传递到侧边栏菜单的输入或参考。

下面我注意我的模型、模板标签、模板的相关部分。希望不会太长。我注意到模型中的类别以进行比较。请注意,此后它是相同的,即类别代码/位置/等与类别替换标签的位置相同。

模型.py

class PaintingDetailPage(Page):
...
    tags = ClusterTaggableManager(through="catalog.PaintingPageTag", blank=True)
    categories = ParentalManyToManyField("catalog.PaintingCategory", blank=True)
...
    @property
    def painting_index_page(self):
        return self.get_parent().specific

    def get_context(self, request, *args, **kwargs):
        context = super(PaintingDetailPage, self).get_context(request, *args, **kwargs)
        context['painting_index_page'] = self.painting_index_page
        context['post'] = self
        return context
class PaintingIndexPage(RoutablePageMixin, Page):
    subtitle = RichTextField...

    def get_context(self, request, *args, **kwargs):
        context = super(PaintingIndexPage, self).get_context(request, *args, **kwargs)
        context['posts'] = self.posts
        context['painting_index_page'] = self
        return context

    def get_posts(self):
        return PaintingDetailPage.objects.descendant_of(self).live()

    @route(r'^tag/(?P<tag>[-\w]+)/$')
    def post_by_tag(self, request, tag, *args, **kwargs):
        self.search_type = 'tag'
        self.search_term = tag
        self.posts = self.get_posts().filter(tags__slug=tag)
        return Page.serve(self, request, *args, **kwargs)
        #return self.render(request)

    @route(r'^category/(?P<category>[-\w]+)/$')
    def post_by_category(self, request, category, *args, **kwargs):
        self.search_type = 'category'
        self.search_term = category
        self.posts = self.get_posts().filter(categories__slug=category)
        return Page.serve(self, request, *args, **kwargs)


# TAGS
class PaintingPageTag(TaggedItemBase):
    content_object = ParentalKey(
        'PaintingDetailPage',
        related_name='post_tags',
        on_delete=models.CASCADE,
    )   
@register_snippet
class Tag(TaggitTag):
    class Meta:
        proxy = True

# CATEGORY
class PaintingCategory(models.Model):
    name = models.CharField(max_length=255)
    slug = AutoSlugField(populate_from="name",editable=True)

    panels =...

    class Meta:
        verbose_name = "Painting Category"
        verbose_name_plural = "Painting Categories"
        ordering = ["name"]

    def __str__(self):
        return self.name
register_snippet(PaintingCategory)

模板标签.py

@register.inclusion_tag('catalog/components/tags_list.html',
                        takes_context=True)
def tags_list(context):
    tags = Tag.objects.all()
    return {
        'request': context['request'],
        'painting_index_page': context['painting_index_page'],
        'tags': tags
    }


@register.inclusion_tag("catalog/components/painting_tags_list.html", takes_context=True)
def painting_tags_list(context):
    page = context["page"]
    painting_tags = page.painting_tags.all()
    return {
        "request": context["request"],
        "tags": tags,
    }

tags_list.html

{% load wagtailroutablepage_tags wagtailcore_tags %}
<div class="card">
...
          {% for tag in tags %}
            <li>
      <a href="{% routablepageurl painting_index_page "post_by_tag" tag.slug %}" class="text-decoration-none">
        <span class="badge bg-secondary">{{ tag }}</span>
      </a>
...
</div>

sidebar.html

{% load catalogapp_tags wagtailroutablepage_tags %}
<div id="mySidebar" class="sidebar">
  <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>
  
  {% categories_list %}
  {% tags_list %}
  
</div>...

【问题讨论】:

    标签: html django-templates menu wagtail templatetags


    【解决方案1】:

    对我来说,错误表明您有一个带有空字符串的标签作为 slug - 错误消息有点难以解开,但它给出了 ('',) 作为传递给 post_by_tag 的参数列表 - 一个列表包含一个参数,空字符串。这对于 URL 模式 @route(r'^tag/(?P&lt;tag&gt;[-\w]+)/$') 无效(要求它至少包含一个字母、数字或连字符)。

    为了确认这一点,我会在tags_list 中添加一个print 行,以准确了解它试图用作slug 的内容:

    @register.inclusion_tag('catalog/components/tags_list.html',
                            takes_context=True)
    def tags_list(context):
        tags = Tag.objects.all()
        print([tag.slug for tag in tags])
        return {
            'request': context['request'],
            'painting_index_page': context['painting_index_page'],
            'tags': tags
        }
    

    如果这确实是问题所在,快速解决方法是使用类似 Tag.objects.exclude(slug='') 的内容过滤掉空白 slug,尽管首先可能值得调查该空白 slug 是如何到达那里的。

    【讨论】:

    • 感谢@gasman 的回归。添加打印行导致'PaintingPageTag'对象没有属性'slug',当我添加Tag.objects.exclude(slug ='')时同上。另外,如果我在某处有一个空的 slug,它是否也应该以同样的方式影响我的 DetailPage 的相同路径?
    • 我不明白添加print 语句是如何导致该错误的——它正在检索Tag 对象并立即打印它们的 slug,所以它会遇到没有意义PaintingPageTag 那个时候的对象。我想你一定同时改变了其他东西。我的怀疑是您在数据库中有一个带有空白 slug 的 Tag 对象,但未附加到页面(因此它在索引页面上 tags_list 使用的 Tag.objects.all 中返回,但它是 not 由page.painting_tags.all() 返回,详情页使用)。
    • 感谢@gasman 的回归。我使用了核选项并删除了数据库和迁移(不是最好的方法,但在这种特殊情况下是最快的)。有用。我不能真正说出是什么造成了这个,但由于我做了一些修改,但并不是所有的都被提交了,所以最合理的原因就是你所说的,即我“必须同时改变其他东西”。话虽如此,在结束这个问题之前,请告知如何记入您的回报。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多