如何将多个ParentalKeys设置为Wagtail TaggedItemBase标签类 [英] How to set multiple ParentalKeys to Wagtail TaggedItemBase tag class

查看:66
本文介绍了如何将多个ParentalKeys设置为Wagtail TaggedItemBase标签类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两种不同的页面模型(没有子类,只有相似字段是"model name","id","parts"等通用字段的单独应用程序),比如说汽车和摩托车.我正在制作一个单独的页面,其中包含其零件表(该表还需要包含"id"(我认为可以是pk,网上商店链接"和"used by"之类的列),这些列将显示所有Bike和Car使用该零件的模型);由于它们可以共享几个相同的部分,因此我希望它们连接到相同的Tag模型(而不是具有"CarPageTag"和"BikePageTag");到目前为止,我已经尝试过:

I have two different page models (no subclassing, separate apps with only similar fields being common ones like "model name", "id", "parts") , let's say, cars and motorcycles. I'm making a separate page with a table of their parts (which also needs to contain columns like "id" which i assume can be a pk,"web store link", and "used by" which will show all Bike and Car models that use the part); Since they can share a few of the same parts, I want for them to be connected to the same Tag model (instead of having "CarPageTag" and "BikePageTag"); What I've tried so far :

  • 我试图为零件"制作一个单独的应用程序.我想出了如何从其他应用程序中包含该类,并且由于以下错误,它可以与汽车或摩托车配合使用,但不能同时与两者配合使用:

AssertionError:ParentalKey(['CarsBlogApp.CarDetailPage','BikesBlogApp.BikeDetailPage'])无效.第一个参数为ForeignKey必须是模型,模型名称或字符串"self"

AssertionError: ParentalKey(['CarsBlogApp.CarDetailPage', 'BikesBlogApp.BikeDetailPage']) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string 'self'

  • 我有一个简单的解决方案,可以通过ManyToManyField在纯Django应用中工作(但我需要在管理员中使用wagtail自动填充标签选择页面)
  • 我到处看过django,wagtail和taggit文档
  • 我浏览了所有的youtube教程

添加models.py 我认为的工作方式:

adding models.py the way I thought It'll work:

PartsApp/models.py:

from django.db import models
from wagtail.core.models import Page
from wagtail.admin.edit_handlers import FieldPanel
from modelcluster.fields import ParentalKey
from taggit.models import TaggedItemBase

class PartsPage(Page):

    templates = "parts/parts_page.html"
    subpage_types = []
    max_count = 1
    parent_page_type = ['home.HomePage']
    paragraph = models.CharField(
        max_length=100,
        blank=False,
        null=False,
        help_text='Overwrites the default title',
    )

    content_panels = Page.content_panels + [
        FieldPanel("paragraph"),
    ]

    class Meta:
        verbose_name = "Needed supplies Page"
        verbose_name_plural = "Needed supplies Pages"

class PartTagPage(TaggedItemBase):
    content_object = ParentalKey(
        ['CarApp.CarDetailPage','BikeApp.BikeDetailPage'],
        related_name='tagged_items',
        on_delete=models.CASCADE,
    )

CarsApp/models.py :

from django.db import models
from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel
from wagtail.core.fields import StreamField
from wagtail.core.models import Page
from wagtail.images.edit_handlers import ImageChooserPanel
from blocks import blocks
from modelcluster.fields import ParentalKey
from modelcluster.contrib.taggit import ClusterTaggableManager
from taggit.models import TaggedItemBase
from PartsApp.models import PartTagPage

class CarListingPage(Page):
    template = "CarsApp/car_listing_page.html"
    subpage_types = ['CarsApp.CarDetailPage']
    parent_page_type = ['home.HomePage']
    max_count = 1
    paragraph = models.CharField(
        max_length=100,
        blank=False,
        null=False,
        help_text='Overwrites the default title',
    )

    content_panels = Page.content_panels + [
        FieldPanel("paragraph"),
    ]

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        all_cars = CarsDetailPage.objects.live().public().order_by('-first_published_at')

        if request.GET.get('tag', None):
            tags = request.GET.get('tag')
            all_cars = all_cars.filter(tags__slug__in=[tags])

        context["cars"] = all_animals
        return context

class CarDetailPage(Page):
    subpage_types = []
    parent_page_types = ['CarsApp.CarsListingPage']
    tags = ClusterTaggableManager(through='PartsApp.PartTagPage', blank=True)
    name = models.CharField(
        max_length=100,
        blank=False,
        null=False,
    )
    model = models.CharField(
        max_length=100,
        blank=False,
        null=False,
    )
    car_image = models.ForeignKey(
        "wagtailimages.Image",
        blank=False,
        null=True,
        related_name="+",
        on_delete=models.SET_NULL,
    )
    description = models.TextField(max_length=10000)

    content_panels = Page.content_panels + [
        FieldPanel("model"),
        FieldPanel("name"),
        FieldPanel("description"),
        FieldPanel("tags"),
        ImageChooserPanel("car_image"),
    ]

BikesApp/models.py几乎相同.再次,这些不起作用.

推荐答案

设置单独的 CarPageTag BikePageTag 模型您想要的解决方案(假设它们是 TaggedItemBase

Setting up separate CarPageTag and BikePageTag models is the solution you want (assuming they're subclasses of TaggedItemBase, as per the pattern shown in the Wagtail documentation).

TaggedItemBase 本身不是标签模型-它只是定义页面模型和标签模型之间的关系(在本例中为 taggit.Tag ,django-taggit库默认提供的标准标签模型).因此, CarPageTag 正在建立 CarPage taggit.Tag 之间的关系,而 BikePageTag 正在建立关系在 BikePage taggit.Tag 之间-两者都使用相同的标签模型.

TaggedItemBase is not a tag model itself - it just defines the relation between the page model and the tag model (which, in this case, is taggit.Tag, the standard tag model provided as default by the django-taggit library). Therefore, CarPageTag is setting up a relation between CarPage and taggit.Tag, and BikePageTag is setting up a relation between BikePage and taggit.Tag - both are using the same tag model.

如果您想要希望汽车和自行车维护自己的独立标签集,则需要使用其他模式-

If you did want cars and bikes to maintain their own independent set of tags, you'd need a different pattern - custom tag models.

这篇关于如何将多个ParentalKeys设置为Wagtail TaggedItemBase标签类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆