将页面对象转换为页面派生对象

时间:2017-09-15 21:00:12

标签: django wagtail

我是新手,但我一直在遇到一些事情,我相信有一个比我目前所做的更好的解决方案。

假设我有一个名为ProductPage的Wagtail页面。让我们说这个页面有一个字段是另一个名为related_product的ProductPage。当我尝试通过以下代码在我的模板或上下文中访问此页面时,

self.related_product

它返回一个Page对象而不是ProductPage对象。因此,我无法通过以下方式转到我真正想要的字段,而不是将其转换为ProductPage对象,

ProductPage.objects.get(page_ptr_id=self.related_product.id)

如果没有上述查询,必须有一种方法来转换它。

1 个答案:

答案 0 :(得分:1)

Page实例转到更具体的模型的标准方法是访问specific属性:

product_page = some_page.specific  # returns a ProductPage instance

但是,这将在内部执行数据库查询,因此它不比上面的代码更有效(只是更具可读性)。如果您的查询集为Page,则可以通过调用查询集上的specific()来略微改进,这将对查询集中存在的每种不同页面类型执行一次额外查询:

product_pages = product_index.get_children().specific()

在您的情况下,有一个更好的解决方案:如果related_product字段仅用于链接到ProductPage而不是任何其他类型的网页,那么您应该通过将外键指向ProductPage而不是Page来在数据模型中指明这一点:

class ProductPage(Page):
    # ...
    related_product = models.ForeignKey('myapp.ProductPage', null=True, blank=True, on_delete=models.SET_NULL)

执行此操作时,访问some_page.related_product将始终为您提供ProductPage个实例。另外一个好处是,Wagtail管理员中的页面选择器弹出窗口将确保您只能选择ProductPages(如果您的所有ProductPages位于页面树中的相同位置,则会直接带您到那里)。