Spec-Zone.ru › Wagtail

Настройки

Модуль wagtail.contrib.settings позволяет определять модели, хранящие настройки, которые могут быть общими для всех записей сайта или специфичными для каждого сайта.

Настройки могут быть изменены администраторами в админпанели Wagtail, а также доступны в коде и шаблонах.

Установка

Добавьте wagtail.contrib.settings в свой INSTALLED_APPS:

INSTALLED_APPS += [
    'wagtail.contrib.settings',
]

Примечание: Если вы используете settings в шаблонах, вам также необходимо обновить настройки TEMPLATES (описаны ниже на этой странице).

Определение настроек

Создайте модель, которая наследуется от:

  • BaseGenericSetting для общих настроек всех сайтов
  • BaseSiteSetting для настроек, специфичных для каждого сайта

и зарегистрируйте её с помощью декоратора register_setting:

from django.db import models
from wagtail.contrib.settings.models import (
    BaseGenericSetting,
    BaseSiteSetting,
    register_setting,
)

@register_setting
class GenericSocialMediaSettings(BaseGenericSetting):
    facebook = models.URLField()

@register_setting
class SiteSpecificSocialMediaSettings(BaseSiteSetting):
    facebook = models.URLField()

Ссылки на ваши настройки появятся в меню Wagtail «Настройки».

Обработчики редактирования

Настройки используют обработчики редактирования, как и остальные компоненты Wagtail. Добавьте настройку panels в свою модель, определяющую все необходимые обработчики редактирования:

@register_setting
class GenericImportantPages(BaseGenericSetting):
    donate_page = models.ForeignKey(
        'wagtailcore.Page', null=True, on_delete=models.SET_NULL, related_name='+'
    )
    sign_up_page = models.ForeignKey(
        'wagtailcore.Page', null=True, on_delete=models.SET_NULL, related_name='+'
    )

    panels = [
        FieldPanel('donate_page'),
        FieldPanel('sign_up_page'),
    ]

@register_setting
class SiteSpecificImportantPages(BaseSiteSetting):
    donate_page = models.ForeignKey(
        'wagtailcore.Page', null=True, on_delete=models.SET_NULL, related_name='+'
    )
    sign_up_page = models.ForeignKey(
        'wagtailcore.Page', null=True, on_delete=models.SET_NULL, related_name='+'
    )

    panels = [
        FieldPanel('donate_page'),
        FieldPanel('sign_up_page'),
    ]

Вы также можете настроить обработчики редактирования как вы это делаете для модели Page с помощью пользовательского атрибута edit_handler:

from wagtail.admin.panels import TabbedInterface, ObjectList

@register_setting
class MySettings(BaseGenericSetting):
    # ...
    first_tab_panels = [
        FieldPanel('field_1'),
    ]
    second_tab_panels = [
        FieldPanel('field_2'),
    ]

    edit_handler = TabbedInterface([
        ObjectList(first_tab_panels, heading='First tab'),
        ObjectList(second_tab_panels, heading='Second tab'),
    ])

Внешний вид

Вы можете изменить метку, используемую в меню, изменив verbose_name вашей модели.

Вы можете добавить значок в меню, передав аргумент icon декоратору register_setting:

@register_setting(icon='placeholder')
class GenericSocialMediaSettings(BaseGenericSetting):
    ...
    class Meta:
        verbose_name = "Social media settings for all sites"

@register_setting(icon='placeholder')
class SiteSpecificSocialMediaSettings(BaseSiteSetting):
    ...
    class Meta:
        verbose_name = "Site-specific social media settings"

Список всех доступных значков можно найти в руководстве по стилю.

Использование настроек

Настройки могут использоваться как в Python-коде, так и в шаблонах.

Использование в Python

Общие настройки

Если вам нужен доступ к общей настройке в представлении, метод BaseGenericSetting.load() позволяет получить общие настройки:

def view(request):
    social_media_settings = GenericSocialMediaSettings.load(request_or_site=request)
    ...

Настройки, специфичные для сайта

Если вам нужен доступ к настройке, специфичной для сайта, в представлении, метод BaseSiteSetting.for_request() позволяет получить настройки, специфичные для текущего запроса:

def view(request):
    social_media_settings = SiteSpecificSocialMediaSettings.for_request(request=request)
    ...

В местах, где запрос недоступен, но вы знаете Site, для которого хотите получить настройки, вы можете использовать BaseSiteSetting.for_site вместо этого:

def view(request):
    social_media_settings = SiteSpecificSocialMediaSettings.for_site(site=user.origin_site)
    ...

Использование в Django-шаблонах

Добавьте обработчик контекста wagtail.contrib.settings.context_processors.settings в свои настройки:

TEMPLATES = [
    {
        ...

        'OPTIONS': {
            'context_processors': [
                ...

                'wagtail.contrib.settings.context_processors.settings',
            ]
        }
    }
]

Затем обратитесь к общим настройкам через {{ settings }}:

{{ settings.app_label.GenericSocialMediaSettings.facebook }}
{{ settings.app_label.SiteSpecificSocialMediaSettings.facebook }}

Примечание: Замените app_label на имя приложения, содержащего вашу модель настроек.

Если вы не в RequestContext, обработчики контекста не будут выполнены, и переменная settings не будет доступна. Чтобы получить settings, используйте предоставленный тег шаблона {% get_settings %}.

{% load wagtailsettings_tags %}
{% get_settings %}
{{ settings.app_label.GenericSocialMediaSettings.facebook }}
{{ settings.app_label.SiteSpecificSocialMediaSettings.facebook }}

По умолчанию, тег создаст или обновит переменную settings в контексте. Если вы хотите назначить её в другую переменную контекста, используйте {% get_settings as other_variable_name %}:

{% load wagtailsettings_tags %}
{% get_settings as wagtail_settings %}
{{ wagtail_settings.app_label.GenericSocialMediaSettings.facebook }}
{{ wagtail_settings.app_label.SiteSpecificSocialMediaSettings.facebook }}

Использование в Jinja2-шаблонах

Добавьте расширение wagtail.contrib.settings.jinja2tags.settings в свои настройки Jinja2:

TEMPLATES = [
    ...

    {
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'APP_DIRS': True,
        'OPTIONS': {
            'extensions': [
                ...

                'wagtail.contrib.settings.jinja2tags.settings',
            ],
        },
    }
]

Затем обратитесь к настройкам через функцию шаблона settings():

{{ settings("app_label.GenericSocialMediaSettings").facebook }}
{{ settings("app_label.SiteSpecificSocialMediaSettings").facebook }}

Примечание: Замените app_label на имя приложения, содержащего вашу модель настроек.

Если request вообще недоступен в шаблоне, вы можете использовать настройки для сайта по умолчанию:

{{ settings("app_label.GenericSocialMediaSettings", use_default_site=True).facebook }}
{{ settings("app_label.SiteSpecificSocialMediaSettings", use_default_site=True).facebook }}

Примечание: Вы не сможете надёжно получить правильный экземпляр настроек для текущего сайта из этого тега шаблона, если объект запроса недоступен. Это актуально только для многосайтовых экземпляров Wagtail.

Вы можете сохранить экземпляр настроек в переменную, чтобы сэкономить на наборе, если вам нужно использовать несколько значений из одной модели:

{% with generic_social_settings=settings("app_label.GenericSocialMediaSettings") %}
    Follow us on Twitter at @{{ generic_social_settings.facebook }},
    or Instagram at @{{ generic_social_settings.instagram }}.
{% endwith %}

{% with site_social_settings=settings("app_label.SiteSpecificSocialMediaSettings") %}
    Follow us on Twitter at @{{ site_social_settings.facebook }},
    or Instagram at @{{ site_social_settings.instagram }}.
{% endwith %}

Или, альтернативно, используя тег set:

{% set generic_social_settings=settings("app_label.GenericSocialMediaSettings") %}
{% set site_social_settings=settings("app_label.SiteSpecificSocialMediaSettings") %}

Использование select_related для повышения эффективности

Для моделей с внешними ключами к другим объектам (например, страницам), которые очень часто используются для вывода значений в шаблонах, вы можете установить атрибут select_related в вашей модели, чтобы Wagtail использовал метод Django QuerySet.select_related() для получения объекта настроек и связанных объектов в одном запросе. Это усложняет начальный запрос, но позволяет свободно обращаться к значениям внешних ключей без дополнительных запросов, что в целом повышает эффективность.

Продолжая пример GenericImportantPages из предыдущего раздела, ниже показано, как установить select_related для повышения эффективности:

@register_setting
class GenericImportantPages(BaseGenericSetting):

    # Fetch these pages when looking up GenericImportantPages for or a site
    select_related = ["donate_page", "sign_up_page"]

    donate_page = models.ForeignKey(
        'wagtailcore.Page', null=True, on_delete=models.SET_NULL, related_name='+'
    )
    sign_up_page = models.ForeignKey(
        'wagtailcore.Page', null=True, on_delete=models.SET_NULL, related_name='+'
    )

    panels = [
        FieldPanel('donate_page'),
        FieldPanel('sign_up_page'),
    ]

С этими дополнениями следующий код шаблона теперь вызовет один запрос к базе данных вместо трёх (один для получения настроек и два для получения каждой страницы):

{% load wagtailcore_tags %}
{% pageurl settings.app_label.GenericImportantPages.donate_page %}
{% pageurl settings.app_label.GenericImportantPages.sign_up_page %}

Использование сокращения настроек page_url

Если, как в предыдущем разделе, ваша модель настроек ссылается на страницы, и вам часто нужно выводить URL этих страниц в вашем проекте, вы можете использовать сокращение page_url вашей модели настроек для более чистого кода. Например, вместо:

{% load wagtailcore_tags %}
{% pageurl settings.app_label.GenericImportantPages.donate_page %}
{% pageurl settings.app_label.GenericImportantPages.sign_up_page %}

Вы можете написать:

{{ settings.app_label.GenericImportantPages.page_url.donate_page }}
{{ settings.app_label.GenericImportantPages.page_url.sign_up_page }}

Использование сокращения page_url имеет несколько преимуществ по сравнению с использованием тега:

  1. Страница «specific» автоматически извлекается для генерации URL, поэтому вам не нужно беспокоиться об этом (или забывать об этом).
  2. Результаты кешируются, поэтому если вам нужно получить тот же URL страницы более чем в одном месте (например, в форме и в навигации подвала), использование сокращения page_url будет более эффективным.
  3. Он более лаконичен, и синтаксис одинаков, независимо от того, используете ли вы его в шаблонах, представлениях или другом Python-коде, что позволяет писать более согласованный код.

При использовании сокращения page_url стоит отметить несколько моментов:

  1. Те же ограничения, что и для тега {% pageurl %}, применяются и к сокращению: если настройки извлекаются из контекста шаблона, где текущий запрос недоступен, все возвращаемые URL будут включать схему/домен сайта, а генерация URL будет не столь эффективной.
  2. Если использовать сокращение в представлениях или другом Python-коде, метод будет генерировать AttributeError, если атрибут, который вы запрашиваете у page_url, не является атрибутом объекта настроек.
  3. Если объект настроек действительно имеет атрибут, но атрибут возвращает значение None (или что-то, что не является Page), сокращение вернёт пустую строку.

© 2014-present Torchbox Ltd and individual contributors.
All rights are reserved.
Licensed under the BSD License.
https://docs.wagtail.org/en/stable/reference/contrib/settings.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API