Wagtail 4.0:修复商品详情页后台编辑与预览路由问题
Wagtail 4.0 解决 RoutablePageMixin 商品页后台编辑/预览问题
方案1:独立商品页 + 索引页路由转发
把商品做成独立的ProductPage作为ProductIndexPage的子页面,后台页面树保持root/products/<prod_name>正常编辑,通过ProductIndexPage的路由处理带分类的前端访问路径。
1. 定义商品页模型
from django.db import models from wagtail.models import Page from wagtail.fields import RichTextField from wagtail.admin.panels import FieldPanel class Category(models.Model): name = models.CharField(max_length=100) slug = models.SlugField(unique=True) def __str__(self): return self.name class ProductPage(Page): category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True) description = RichTextField(blank=True) content_panels = Page.content_panels + [ FieldPanel('category'), FieldPanel('description'), ] # 限制只能作为ProductIndexPage的子页面 parent_page_types = ['your_app.ProductIndexPage'] subpage_types = [] # 不允许添加子页面
2. 修改索引页模型(带RoutablePageMixin)
from wagtail.contrib.routable_page.models import RoutablePageMixin, path from django.shortcuts import get_object_or_404 from .models import ProductPage class ProductIndexPage(RoutablePageMixin, Page): content_panels = Page.content_panels + [ # 可添加索引页自身的内容字段 ] # 允许添加ProductPage作为子页面 subpage_types = ['your_app.ProductPage'] # 带分类的商品详情路由 @path('<str:cat_name>/<str:prod_name>/') def product_detail(self, request, cat_name, prod_name): # 根据分类slug和商品slug找到对应页面 product = get_object_or_404(ProductPage, slug=prod_name, category__slug=cat_name) # 直接渲染商品页内容 return self.render( request, template=product.get_template(), context=product.get_context(request) ) # 默认的商品列表路由 @path('') def product_list(self, request): return self.render(request)
方案2:修改商品页URL生成逻辑
让商品页的前端URL带分类,但后台依然使用默认的页面树路径进行编辑预览。
1. 修改商品页的get_url方法
class ProductPage(Page): # 字段同方案1 category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True) def get_url(self, request=None, current_site=None): # 生成带分类的前端URL if self.category and self.category.slug: return f"/products/{self.category.slug}/{self.slug}/" # 无分类时使用默认URL return super().get_url(request, current_site)
2. 索引页路由处理
class ProductIndexPage(RoutablePageMixin, Page): @path('<str:cat_name>/<str:prod_name>/') def product_detail(self, request, cat_name, prod_name): product = get_object_or_404(ProductPage, slug=prod_name, category__slug=cat_name) # 重定向到商品页的实际URL(或直接渲染) return redirect(product)
关键说明
原来的写法问题在于:RoutablePageMixin的路由是挂载在ProductIndexPage的URL(root/products/)下,生成的路径是root/products/<cat_name>/<prod_name>/,但后台的商品页实际路径是root/products/<prod_name>/,两者不匹配导致后台编辑预览按钮跳转的路径无法被路由识别。
上面的方案都保持了后台页面树的路径与页面实际URL一致,同时通过路由转发或URL重写实现了前端友好的带分类路径,后台编辑预览功能不受影响。
内容的提问来源于stack exchange,提问作者Jordano Bruno
相关产品推荐
相关产品推荐

