在Wagtail中获取另一页的数据以获取受密码保护的版本

时间:2019-04-05 15:03:56

标签: python wagtail

我是Python和Wagtail的新手。我正在使用Wagtail网站进行大部分工作,但遇到一个问题。

该站点将显示一组零售(已完成和正在使用)的产品(工厂),以及用于贸易的同一组产品,并显示仅贸易价。我有PlantIndexPagePlantPage Wa模型,后者具有各种产品领域和两个价格领域。

贸易价格信息应使用Wagtail's 'page privacy'密码选项进行密码保护,因此我认为我需要一个单独的索引页面(TradePlantIndexPage),可以在Wagtail管理员中将此页面隐私设置应用到该页面。 ,以有效地包含其自己的PlantPage公共产品页面的交易版本。

因此,我有很多PlantPage页(每个植物产品一个),并且一个 TradePlantPage页使用RoutablePageMixin@route接受任何PlantPage产品的the。

# working: /plants/
class PlantIndexPage(Page):
    def get_context(self, request):
        context = super().get_context(request)
        context['plants'] = Page.objects.exact_type(PlantPage).live().all().order_by('title')
        return context

# working, password protected: /trade/
class TradePlantIndexPage(PlantIndexPage):
    template = 'plants/plant_index_page.html'  # for PlantIndexPage and TradePlantIndexPage

    def get_context(self, request):
        context = super().get_context(request)
        context['trade'] = True  # condition in template depends on this to show trade prices
        return context

# working: /plants/<plant_page_slug>
class PlantPage(Page):
    price_retail = models.DecimalField(...)
    price_trade = models.DecimalField(...)
    # ...

# not yet working: /trade/plant/<plant_page_slug>
class TradePlantPage(RoutablePageMixin, PlantPage):
    parent_page_types = ['TradePlantIndexPage']
    subpage_types = []

    template = 'plants/plant_page.html'  # for PlantPage and TradePlantPage

    def get_context(self, request):
        context = super().get_context(request)
        context['trade'] = True  # condition in template depends on this to show trade price
        context['plant'] = Page.objects.page(???).live()  # how to get PlantPage by slug?
        return context

    @route(r'^([-\w]+)/$')
    def trade(self, request, plant_slug):
        self.trade = True
        # how to render TradePlantPage with PlantPage content based on plant_slug?

我将使用TradePlantIndexPage的植物列表链接到可使用TradePlantPage/trade/plant/<plant_page_slug>)而不是PlantPage({{1} }。

要显示带有/plants/<plant_page_slug>的特定植物,如何基于TradePlantPage PlantPage的{​​{1}}获取trade的正确实例,并且设置上下文,以便使用@route变量来plant_slug的模板起作用?

我在代码中附加了与此相关的注释/问题。谢谢。


更新

感谢加斯曼的友好和易于理解的答案,PlantPage的贸易路线正在运作。按照该答案的建议使用page而不是TradePlantPage,我将plant的上下文方法更新为:

page

这是可行的,但是我想知道PlantPage是否是在共享模板中使用 def get_context(self, request): context = super().get_context(request) context['trade'] = False context['plant'] = context['page'] return context 而不是context['plant'] = context['page']的次佳方式。例如,我想它会使用于字段数据的内存增加一倍?无论如何,对于这个小型网站来说,这可能不是问题,除非有其他声音,否则我将使用它。

1 个答案:

答案 0 :(得分:0)

RoutablePageMixin路由方法中,返回HTTP响应的过程与在普通Django视图函数中的工作方式相同-请参见Django's 'Views and templates' tutorial。页面的template属性和get_context方法不使用,除非您明确地将它们连接起来(并且为简单起见,我建议不要这样做,并直接设置模板和上下文变量在方法中)。

您的路线方法将需要执行以下操作:

  • 基于PlantPage检索正确的plant_slug-为此,我们将使用Django的get_object_or_404帮助程序
  • 呈现模板plants/plant_page.html,并向其传递上下文变量trade(设置为True),plant(设置为检索到的PlantPage)和page(设置为当前页面,即TradePlantPage对象)。

这为我们提供了代码:

from django.shortcuts import get_object_or_404, render

class TradePlantPage(RoutablePageMixin, PlantPage):
    parent_page_types = ['TradePlantIndexPage']
    subpage_types = []

    @route(r'^([-\w]+)/$')
    def trade(self, request, plant_slug):
        plant = get_object_or_404(PlantPage, slug=plant_slug)

        return render(request, 'plants/plant_page.html', {
            'trade': True,
            'plant': plant,
            'page': self,
        })

注意:这里我假设您的plant_page.html模板已设置为在同时从plantPlantPage进行调用时期望变量TradePlantPage-例如您使用{{ plant.title }}而不是{{ page.title }}输出工厂名称。如果不是这种情况,则可以通过在上面的代码中设置PlantPage来将page对象作为'page': plant,来传递。但是,我建议最好给模板访问当前正在渲染的“真实”页面对象的权限-这样您就可以在网站导航中突出显示正确的项目。