Получение данных другой страницы для защищенной паролем версии в Wagtail - PullRequest
1 голос
/ 05 апреля 2019

Я новичок в Python и Wagtail.У меня есть большая часть пути с сайтом Wagtail, над которым я работаю, но я застрял в одном вопросе.

Сайт должен показать набор продуктов (растений) для розничной торговли (готово и работает)и тот же набор для торговли с показанными только для торговли ценами.У меня есть модели PlantIndexPage и PlantPage Wagtail, причем последние имеют различные поля продукта и два поля цены.

Информация о торговой цене должна быть защищена паролем с помощью Wagtail 'page privacy' опция пароля, и поэтому я считаю, что мне нужна отдельная страница указателя (TradePlantIndexPage), к которой я могу применить эту настройку конфиденциальности страницы в администраторе Wagtail, чтобы эффективно содержать собственные торговые версии общедоступных PlantPage страниц продукта.

Итак, у меня много PlantPage страниц (по одной на каждый растительный продукт) и одна TradePlantPage страница с использованием RoutablePageMixin с @route для принятияслаг любого продукта PlantPage.

# 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 со ссылкой на URL, по которому доступен TradePlantPage (/trade/plant/<plant_page_slug>) вместо PlantPage (/plants/<plant_page_slug>).

Для отображения конкретного растения с помощью TradePlantPage, как я могу получить правильный экземпляр PlantPage на основе 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']неоптимальный способ использования plant вместо page в общем шаблоне.Я полагаю, это удваивает объем памяти, используемой для полевых данных, например?Вероятно, не проблема для этого небольшого сайта, и я буду использовать его, если не услышу иначе.

1 Ответ

0 голосов
/ 05 апреля 2019

В методе маршрутизации RoutablePageMixin процесс возврата HTTP-ответа работает так же, как и в обычной функции представления Django - см. Учебное пособие Django 'Представления и шаблоны' .Свойство 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 настроен на ожидание переменнойplant при вызове из PlantPage и TradePlantPage - например, вы используете {{ plant.title }} вместо {{ page.title }} для вывода названия завода.Если это не так, то, вероятно, можно передать объект PlantPage как page, установив 'page': plant, в приведенном выше коде.Однако я бы посоветовал предоставить шаблону доступ к «реальному» объекту страницы, отображаемому в данный момент, - чтобы вы могли выделить нужный элемент в навигации по вашему сайту, например.

...