【问题标题】:Is it possible in Wagtail to use a proxy model with RoutablePageMixin?Wagtail 是否可以使用带有 RoutablePageMixin 的代理模型?
【发布时间】:2020-09-09 20:54:38
【问题描述】:

我的 Wagtail 网站有一些可以在画廊应用程序中查看的项目,用户可以对其进行编辑,以便它也可以在商店应用程序中显示为项目。这严格来说是一对一的,所以我不希望他们单独管理这些项目。我认为代理模型可能是实现这一目标的最佳方式,但我遇到了困难,没有找到很多关于在 Wagtail 中使用代理模型的文档。也可能我的正则表达式不好。

在应用“图库”中:

class GalleryItem(Page):
    parent_page_types = ['InstallationPage']

    description = models.CharField(blank=True, max_length=250)
    direct_sale = models.BooleanField("Direct Sale", default=False, help_text="Check this box to list this item for sale directly on your website.")
    direct_sale_price = models.DecimalField("Sale price, $", blank=True, null=True, max_digits=6, decimal_places=2, help_text="Add more info about this item for the store page only.")
    direct_sale_extra_description = models.CharField("Addtional sale description (optional)", blank=True, max_length=250, )
    stock = models.IntegerField("Number in stock", blank=True, null=True,)

在应用“商店”中:

from gallery.models import GalleryImage

class Shop(Page):

    def get_context(self, request):
        
        context = super().get_context(request)
        shop_items = ShopItem.objects.filter(Q(direct_sale=True) | Q(external_sale=True))
        paginator = Paginator(shop_items, 24)
        page = request.GET.get('page')

        try:
            pagin = paginator.get_page(page)
        except PageNotAnInteger:
            pagin = paginator.get_page(1)
        context['shop_items'] = shop_items

        return context

class ShopItem(GalleryItem, RoutablePageMixin):
    class Meta:
        proxy = True

    parent_page_types = ['Shop']

    @route(r"^shop/(?P<item_slug>[-\w]*)/$", name="item_view")
    def item_view(self, request, item_slug):
    # ????? Trying different things here:
        context = self.get_context(request)
        try:
            item = ShopItem.objects.get(slug=item_slug)
        except Exception:
             item = None

        if item is None:
            # 404
            pass
        context["item"] = item
    
        return render(request, "shop/shop_item.html", context)

画廊项目可以在/gallery/item-slug查看。我还想在/shop/item-slug 使用不同的模板查看该项目,但是我只能实现 404 页面。

【问题讨论】:

    标签: django wagtail


    【解决方案1】:

    RoutablePageMixin 无法按照您想象的方式工作。为了让它工作,页面必须存在于页面树中,并且可以通过正常的基于路径的 URL 找到;然后相对于该路径处理其中定义的任何路由。所以,如果你在/foo/bar/baz/ 有一个RoutablePageMixin 页面,它用@route(r'^shop/([-\w]*)/$') 定义了一个视图方法,该方法将响应像/foo/bar/baz/shop/item-slug/ 这样的URL。由于您的树没有任何实际将自己标识为ShopItem 的页面,因此将永远无法到达那里定义的路由。

    您根本不需要ShopItem 模型-您所做的只是响应/shop/ 的子路径,这可能是您的Shop 页面的URL,因此您可以创建Shop改为 RoutablePageMixin 页面:

    from django.shortcuts import get_object_or_404
    
    class Shop(RoutablePageMixin, Page):
    
        def get_context(self, request):
            # ... logic for the main /shop/ page, as before
    
        @route(r'^([-\w]+)/$')  # view method for subpaths of /shop/
        def item_view(self, request, item_slug):
            item = get_object_or_404(GalleryItem, slug=item_slug)
            return render(request, "shop/shop_item.html", {'item': item})
    

    【讨论】:

    • 非常感谢!它完全符合我的要求。但是,我在项目的模型管理员 /admin/shop/shopitem/ 中保留了代理模型以获得一条不错的路线。如果我花更多时间在普通的 Django 上,这对我来说可能会更容易。
    猜你喜欢
    • 1970-01-01
    • 2020-01-08
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-31
    相关资源
    最近更新 更多