Обработчики
При загрузке Wagtail будет искать любой приложение с файлом wagtail_hooks.py и выполнять его содержимое. Это предоставляет способ зарегистрировать собственные функции для выполнения в определенные моменты выполнения Wagtail, например, при сохранении страницы или при построении основного меню.
Примечание
Обработчики обычно используются для настройки поведения на уровне отображения Wagtail админки и фронтенда. Для настроек, которые связаны только с поведением на уровне модели - например, для вызова внешнего сервиса при добавлении страницы или документа - часто лучше использовать механизм сигналов Django механизм сигналов Django (см. также: Сигналы Wagtail), так как они не зависят от того, проходит ли пользователь определенный путь через админский интерфейс.
Регистрация функций с помощью обработчика Wagtail выполняется с помощью декоратора @hooks.register:
from wagtail import hooks
@hooks.register('name_of_hook')
def my_hook_function(arg1, arg2...)
# your code here
В качестве альтернативы, можно вызвать hooks.register как обычную функцию, передав имя обработчика и функцию-обработчик, определенную в другом месте:
hooks.register('name_of_hook', my_hook_function)
Если вам нужно, чтобы ваши обработчики выполнялись в определенном порядке, вы можете передать параметр order. Если порядок не указан, обработчики выполняются в порядке, заданном INSTALLED_APPS. Wagtail также использует обработчики внутри себя, поэтому при переопределении встроенных функций Wagtail необходимо учитывать порядок (например, при удалении элементов сводки по умолчанию):
@hooks.register('name_of_hook', order=1) # This will run after every hook in the wagtail core
def my_hook_function(arg1, arg2...)
# your code here
@hooks.register('name_of_hook', order=-1) # This will run before every hook in the wagtail core
def my_other_hook_function(arg1, arg2...)
# your code here
@hooks.register('name_of_hook', order=2) # This will run after `my_hook_function`
def yet_another_hook_function(arg1, arg2...)
# your code here
Тестирование обработчиков
Обработчики обычно регистрируются при запуске и не могут быть изменены во время выполнения. Но при написании unit-тестов вам, возможно, захочется зарегистрировать функцию-обработчик только для одного теста или блока кода и отменить её регистрацию, чтобы она не выполнялась при запуске других тестов.
Вы можете временно зарегистрировать обработчики, используя функцию hooks.register_temporarily, которая может использоваться как декоратор, так и контекстный менеджер. Вот пример того, как зарегистрировать функцию-обработчик только для одного теста:
def my_hook_function():
pass
class MyHookTest(TestCase):
@hooks.register_temporarily('name_of_hook', my_hook_function)
def test_my_hook_function(self):
# Test with the hook registered here
pass
А вот пример регистрации функции-обработчика для одного блока кода:
def my_hook_function():
pass
with hooks.register_temporarily('name_of_hook', my_hook_function):
# Hook is registered here
..
# Hook is unregistered here
Если вам нужно зарегистрировать несколько обработчиков в блоке with, вы можете передать их как список кортежей:
def my_hook(...):
pass
def my_other_hook(...):
pass
with hooks.register_temporarily([
('hook_name', my_hook),
('hook_name', my_other_hook),
]):
# All hooks are registered here
..
# All hooks are unregistered here
Доступные обработчики перечислены ниже.
Модули администрирования
Фиксаторы для создания новых областей админ-интерфейса (наряду со страницами, изображениями, документами и так далее).
construct_homepage_panels
Добавить или удалить панели с главной страницы Wagtail админки. Передаваемая в этот фиксатор вызываемая функция должна принять объект request и список объектов панели, и должна изменить этот список по мере необходимости. Объекты панели являются Шаблонными компонентами с дополнительным свойством order, целым числом, определяющим позицию панели в окончательном отсортированном списке. Панели по умолчанию используют целые числа между 100 и 300.
from django.utils.safestring import mark_safe
from wagtail.admin.ui.components import Component
from wagtail import hooks
class WelcomePanel(Component):
order = 50
def render_html(self, parent_context):
return mark_safe("""
<section class="panel summary nice-padding">
<h3>No, but seriously -- welcome to the admin homepage.</h3>
</section>
""")
@hooks.register('construct_homepage_panels')
def add_another_welcome_panel(request, panels):
panels.append(WelcomePanel())
construct_homepage_summary_items
Добавить или удалить элементы из панели «Краткое описание сайта» на главной странице админки (которая отображает количество страниц и других объектов, существующих на сайте). Передаваемая в этот фиксатор вызываемая функция должна принять объект request и список объектов элемента краткого описания, и должна изменить этот список по мере необходимости. Объекты элемента краткого описания являются экземплярами wagtail.admin.site_summary.SummaryItem, который расширяет класс Component следующими дополнительными методами и свойствами:
describe_collection_contents
Вызывается, когда Wagtail нужно узнать, какие объекты существуют в коллекции, если таковые есть. В настоящее время это происходит при подтверждении перед удалением коллекции, чтобы убедиться, что пустые коллекции не могут быть удалены. Передаваемая в этот фиксатор вызываемая функция получит объект collection и должна вернуть либо None (чтобы указать отсутствие объектов в этой коллекции), либо словарь, содержащий следующие ключи:
-
count- числовое количество элементов в этой коллекции -
count_text- удобочитаемая строка, описывающая количество элементов в этой коллекции, например, «3 документа». (В сайтах с поддержкой нескольких языков здесь следует вернуть переводимую строку, скорее всего, используя функциюdjango.utils.translation.ngettext.) -
url(необязательно) - URL страницы индекса, которая перечисляет описываемые объекты.
register_account_settings_panel
Регистрирует новый класс панели настроек для добавления в представление «Аккаунт» в админке.
Этот фиксатор может быть добавлен в подкласс BaseSettingsPanel. Например:
from wagtail.admin.views.account import BaseSettingsPanel
from wagtail import hooks
@hooks.register('register_account_settings_panel')
class CustomSettingsPanel(BaseSettingsPanel):
name = 'custom'
title = "My custom settings"
order = 500
form_class = CustomSettingsForm
В качестве альтернативы, он также может быть добавлен в функцию. Например, эта функция эквивалентна вышеприведенной:
from wagtail.admin.views.account import BaseSettingsPanel
from wagtail import hooks
class CustomSettingsPanel(BaseSettingsPanel):
name = 'custom'
title = "My custom settings"
order = 500
form_class = CustomSettingsForm
@hooks.register('register_account_settings_panel')
def register_custom_settings_panel(request, user, profile):
return CustomSettingsPanel(request, user, profile)
Дополнительные сведения о доступных параметрах можно найти в Настройка формы настроек учетной записи пользователя.
register_admin_urls
Регистрация дополнительных URL-адресов страниц админки. Вызываемая функция, переданная в этот фиксатор, должна вернуть список шаблонов Django URL, которые определяют структуру страниц и конечных точек вашего расширения для админки Wagtail. Более подробную информацию о стандартных Django URLconf и представлениях см. в диспетчере URL-адресов.
from django.http import HttpResponse
from django.urls import path
from wagtail import hooks
def admin_view(request):
return HttpResponse(
"I have approximate knowledge of many things!",
content_type="text/plain")
@hooks.register('register_admin_urls')
def urlconf_time():
return [
path('how_did_you_almost_know_my_name/', admin_view, name='frank'),
]
register_group_permission_panel
Добавление новой панели в форму «Группы» в области «Настройки». Передаваемая в этот фиксатор вызываемая функция должна вернуть класс ModelForm/ModelFormSet, с конструктором, который принимает объект группы в качестве ключевого аргумента instance и который реализует методы save, is_valid и as_admin_panel (который возвращает HTML для включения на странице редактирования группы).
register_admin_search_area
Добавление элемента в поиск Wagtail админки «Другие поиски». Поведение этого фиксатора аналогично register_admin_menu_item. Передаваемая в этот фиксатор вызываемая функция должна вернуть экземпляр wagtail.admin.search.SearchArea. Новые элементы могут быть созданы из класса SearchArea, передавая следующие параметры:
-
label- текст, отображаемый в поле «Другие поиски». -
name- внутреннее имя, используемое для идентификации варианта поиска; по умолчанию соответствует slugified форме метки. -
url- URL целевой страницы поиска. -
classnames- произвольные имена CSS-классов, применяемые к ссылке -
icon_name- иконка для отображения рядом с меткой. -
attrs- дополнительные HTML-атрибуты для применения к ссылке. -
order- целое число, определяющее позицию элемента в списке вариантов.
Установка URL может быть достигнута с помощью reverse() на целевой странице поиска. Параметр GET ‘q’ будет добавлен к заданному URL.
В шаблоне предоставлена метка search_other модулем шаблонов wagtailadmin_tags. Эта метка принимает один необязательный параметр current, который позволяет указать name варианта поиска, который в данный момент активен. Если параметр не указан, фиксатор по умолчанию выполняет обратный поиск URL страницы для сравнения с параметром url.
SearchArea можно унаследовать, чтобы настроить вывод HTML, указать необходимые JavaScript-файлы, или условно отображать или скрывать элемент для определенных запросов (например, для применения проверок разрешений); см. исходный код (wagtail/admin/search.py) для получения подробностей.
from django.urls import reverse
from wagtail import hooks
from wagtail.admin.search import SearchArea
@hooks.register('register_admin_search_area')
def register_frank_search_area():
return SearchArea('Frank', reverse('frank'), icon_name='folder-inverse', order=10000)
register_permissions
Возвращает QuerySet объектов Permission, которые необходимо отобразить в области администрирования «Группы».
from django.contrib.auth.models import Permission
from wagtail import hooks
@hooks.register('register_permissions')
def register_permissions():
app = 'blog'
model = 'extramodelset'
return Permission.objects.filter(content_type__app_label=app, codename__in=[
f"view_{model}", f"add_{model}", f"change_{model}", f"delete_{model}"
])
filter_form_submissions_for_user
Позволяет настраивать доступ к отправленным формам на основе пользователя и формы.
Этот фиксатор принимает два параметра:
- Пользователь, пытающийся получить доступ к отправкам форм
- Список страниц форм
QuerySet
Фиксатор должен вернуть QuerySet, содержащий подмножество этих страниц форм, к которым пользователю разрешен доступ к отправкам.
Например, чтобы предотвратить доступ не-суперпользователей к отправкам форм:
from wagtail import hooks
@hooks.register('filter_form_submissions_for_user')
def construct_forms_for_user(user, queryset):
if not user.is_superuser:
queryset = queryset.none()
return queryset
Интерфейс редактора
Обработчики для настройки интерфейса редактирования страниц и фрагментов.
register_rich_text_features
Поля rich text в Wagtail работают со списком идентификаторов «функций», которые определяют, какие элементы управления редактированием доступны в редакторе и какие элементы разрешены в выводе; например, поле rich text, определённое как RichTextField(features=['h2', 'h3', 'bold', 'italic', 'link']), позволит использовать заголовки, форматирование полужирным/курсивом и ссылки, но не (например) маркированные списки или изображения. Обработчик register_rich_text_features позволяет определять новые идентификаторы функций — см. Ограничение функций в поле rich text для получения подробной информации.
insert_editor_css
Добавление дополнительных файлов CSS или фрагментов в редактор страницы.
from django.templatetags.static import static
from django.utils.html import format_html
from wagtail import hooks
@hooks.register('insert_editor_css')
def editor_css():
return format_html(
'<link rel="stylesheet" href="{}">',
static('demo/css/vendor/font-awesome/css/font-awesome.min.css')
)
insert_global_admin_css
Добавление дополнительных файлов CSS или фрагментов кода на все страницы админки.
from django.utils.html import format_html
from django.templatetags.static import static
from wagtail import hooks
@hooks.register('insert_global_admin_css')
def global_admin_css():
return format_html('<link rel="stylesheet" href="{}">', static('my/wagtail/theme.css'))
insert_editor_js
Добавление дополнительных файлов JavaScript или фрагментов кода в редактор страницы.
from django.utils.html import format_html_join
from django.utils.safestring import mark_safe
from django.templatetags.static import static
from wagtail import hooks
@hooks.register('insert_editor_js')
def editor_js():
js_files = [
'js/fireworks.js', # https://fireworks.js.org
]
js_includes = format_html_join('\n', '<script src="{0}"></script>',
((static(filename),) for filename in js_files)
)
return js_includes + mark_safe(
"""
<script>
window.addEventListener('DOMContentLoaded', (event) => {
var container = document.createElement('div');
container.style.cssText = 'position: fixed; width: 100%; height: 100%; z-index: 100; top: 0; left: 0; pointer-events: none;';
container.id = 'fireworks';
document.getElementById('main').prepend(container);
var options = { "acceleration": 1.2, "autoresize": true, "mouse": { "click": true, "max": 3 } };
var fireworks = new Fireworks(document.getElementById('fireworks'), options);
fireworks.start();
});
</script>
"""
)
insert_global_admin_js
Добавление дополнительных файлов JavaScript или фрагментов кода на все страницы админки.
from django.utils.safestring import mark_safe
from wagtail import hooks
@hooks.register('insert_global_admin_js')
def global_admin_js():
return mark_safe(
'<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r74/three.js"></script>',
)
Рабочий процесс редактора
Фишки для настройки способа навигации пользователей по процессу создания контента страницы.
after_create_page
Выполните какие-либо действия с объектом Page после его сохранения в базе данных (в качестве опубликованной страницы или пересмотра). Передаваемая в эту фишку вызываемая функция должна принимать объект request и объект page. Функция не обязана возвращать ничего, но если возвращается объект со свойством status_code, Wagtail будет использовать его в качестве объекта ответа. По умолчанию Wagtail перенаправит пользователя на страницу «Обзор» для родительской страницы новой страницы.
from django.http import HttpResponse
from wagtail import hooks
@hooks.register('after_create_page')
def do_after_page_create(request, page):
return HttpResponse("Congrats on making content!", content_type="text/plain")
Если вы задаёте атрибуты объекта Page, вы также должны вызвать save_revision(), так как представление «Редактировать» и представление «Индекс» берут свои данные из таблицы пересмотров, а не из фактического сохранённого записей страницы.
@hooks.register('after_create_page')
def set_attribute_after_page_create(request, page):
page.title = 'Persistent Title'
new_revision = page.save_revision()
if page.live:
# page has been created and published at the same time,
# so ensure that the updated title is on the published version too
new_revision.publish()
before_create_page
Вызывается в начале представления «создание страницы», передавая запрос, родительскую страницу и класс модели страницы.
Функция не обязана возвращать ничего, но если возвращается объект со свойством status_code, Wagtail будет использовать его в качестве объекта ответа и пропустит остальную часть представления.
В отличие от after_create_page, это выполняется как для запросов GET, так и для запросов POST.
Это можно использовать для полной замены редактора на уровне отдельного представления:
from wagtail import hooks
from .models import AwesomePage
from .admin_views import edit_awesome_page
@hooks.register('before_create_page')
def before_create_page(request, parent_page, page_class):
# Use a custom create view for the AwesomePage model
if page_class == AwesomePage:
return create_awesome_page(request, parent_page)
after_delete_page
Выполните какие-либо действия после удаления объекта Page. Использует тот же механизм, что и after_create_page.
before_delete_page
Вызывается в начале представления «удаление страницы», передавая запрос и объект страницы.
Использует тот же механизм, что и before_create_page, выполняется как для запросов GET, так и для запросов POST.
from django.shortcuts import redirect
from django.utils.html import format_html
from wagtail.admin import messages
from wagtail import hooks
from .models import AwesomePage
@hooks.register('before_delete_page')
def before_delete_page(request, page):
"""Block awesome page deletion and show a message."""
if request.method == 'POST' and page.specific_class in [AwesomePage]:
messages.warning(request, "Awesome pages cannot be deleted, only unpublished")
return redirect('wagtailadmin_pages:delete', page.pk)
after_edit_page
Выполните какие-либо действия с объектом Page после его обновления. Использует тот же механизм, что и after_create_page.
before_edit_page
Вызывается в начале представления «редактирование страницы», передавая запрос и объект страницы.
Использует тот же механизм, что и before_create_page.
after_publish_page
Выполните какие-либо действия с объектом Page после его публикации через представление «создание страницы» или представление «редактирование страницы».
Функция не обязана возвращать ничего, но если возвращается объект со свойством status_code, Wagtail будет использовать его в качестве объекта ответа и пропустит остальную часть представления.
before_publish_page
Выполните какие-либо действия с объектом Page перед его публикацией через представление «создание страницы» или представление «редактирование страницы».
Функция не обязана возвращать ничего, но если возвращается объект со свойством status_code, Wagtail будет использовать его в качестве объекта ответа и пропустит остальную часть представления.
after_unpublish_page
Вызывается после действия «снятия с публикации» в представлении «снятие с публикации», передавая запрос и объект страницы.
Функция не обязана возвращать ничего, но если возвращается объект со свойством status_code, Wagtail будет использовать его в качестве объекта ответа и пропустит остальную часть представления.
before_unpublish_page
Вызывается перед действием «снятие с публикации» в представлении «снятие с публикации», передавая запрос и объект страницы.
Функция не обязана возвращать ничего, но если возвращается объект со свойством status_code, Wagtail будет использовать его в качестве объекта ответа и пропустит остальную часть представления.
after_copy_page
Выполните какие-либо действия с объектом Page после его копирования, передавая запрос, объект страницы и новую скопированную страницу. Использует тот же механизм, что и after_create_page.
before_copy_page
Вызывается в начале представления «копирование страницы», передавая запрос и объект страницы.
Использует тот же механизм, что и before_create_page.
after_move_page
Выполните какие-либо действия с объектом Page после его перемещения, передавая запрос и объект страницы. Использует тот же механизм, что и after_create_page.
before_move_page
Вызывается в начале представления «перемещение страницы», передавая запрос, объект страницы и объект страницы назначения.
Использует тот же механизм, что и before_create_page.
before_convert_alias_page
Вызывается в начале представления convert_alias, которое отвечает за преобразование страниц-псевдонимов в обычные страницы Wagtail.
Запрос и преобразуемая страница передаются в качестве аргументов фишки.
Функция не обязана возвращать ничего, но если возвращается объект со свойством status_code, Wagtail будет использовать его в качестве объекта ответа и пропустит остальную часть представления.
after_convert_alias_page
Выполните какие-либо действия с объектом Page после его преобразования из псевдонима.
Запрос и страница, которая только что была преобразована, передаются в качестве аргументов фишки.
Функция не обязана возвращать ничего, но если возвращается объект со свойством status_code, Wagtail будет использовать его в качестве объекта ответа и пропустит остальную часть представления.
construct_translated_pages_to_cascade_actions
Возвращает дополнительные страницы для обработки в синхронизированной структуре дерева.
Эта фишка вызывается только при снятии страницы с публикации, когда WAGTAIL_I18N_ENABLED = True.
Список страниц и действие передаются в качестве аргументов фишки.
Функция должна вернуть словарь с страницей из списка страниц в качестве ключа и списком дополнительных страниц для выполнения действия. Мы рекомендуем, чтобы они были не псевдонимами, прямыми переводами страниц из аргумента функции.
construct_wagtail_userbar
Добавляет или удаляет элементы из панели инструментов wagtail. По умолчанию предоставляются инструменты добавления, редактирования и модерации. Вызываемая функция, переданная в фишку, должна принимать объект request и список объектов меню items. Объекты элементов меню должны иметь метод render, который может принять объект request и вернуть строку HTML, представляющую элемент меню. Для получения дополнительной информации обратитесь к шаблонам панели инструментов и классам элементов меню.
from wagtail import hooks
class UserbarPuppyLinkItem:
def render(self, request):
return '<li><a href="http://cuteoverload.com/tag/puppehs/" ' \
+ 'target="_parent" role="menuitem" class="action icon icon-wagtail">Puppies!</a></li>'
@hooks.register('construct_wagtail_userbar')
def add_puppy_link_item(request, items):
return items.append( UserbarPuppyLinkItem() )
Рабочий процесс администратора
Обработчики для настройки способа, которым администраторы направляются по процессу редактирования пользователей.
after_create_user
Выполните какие-либо действия с объектом User после сохранения его в базе данных. Передаваемый в этот обработчик вызываемый объект должен принять объект request и объект user. Функция не обязана возвращать ничего, но если возвращается объект со свойством status_code, Wagtail будет использовать его как объект ответа. По умолчанию Wagtail перенаправляет на страницу списка пользователей.
from django.http import HttpResponse
from wagtail import hooks
@hooks.register('after_create_user')
def do_after_create_user(request, user):
return HttpResponse("Congrats on creating a new user!", content_type="text/plain")
before_create_user
Вызывается в начале представления «создание пользователя», передавая запрос.
Функция не обязана возвращать ничего, но если возвращается объект со свойством status_code, Wagtail будет использовать его как объект ответа и пропустит остальную часть представления.
В отличие от after_create_user, этот обработчик выполняется как для запросов GET, так и для запросов POST.
Это можно использовать для полного переопределения редактора пользователей на основе представления:
from django.http import HttpResponse
from wagtail import hooks
from .models import AwesomePage
from .admin_views import edit_awesome_page
@hooks.register('before_create_user')
def do_before_create_user(request):
return HttpResponse("A user creation form", content_type="text/plain")
after_delete_user
Выполните какие-либо действия после удаления объекта User. Используется тот же метод, что и в after_create_user.
before_delete_user
Вызывается в начале представления «удаление пользователя», передавая запрос и объект пользователя.
Используется тот же метод, что и в before_create_user.
after_edit_user
Выполните какие-либо действия с объектом User после его обновления. Используется тот же метод, что и в after_create_user.
before_edit_user
Вызывается в начале представления «редактирование пользователя», передавая запрос и объект пользователя.
Используется тот же метод, что и в before_create_user.
Выбиратели
construct_page_chooser_queryset
Вызывается при отрисовке представления выбора страницы, чтобы разрешить настройку набора результатов запроса списка страниц. Вызываемый объект, переданный в обработчик, получит текущий набор результатов запроса страницы и объект запроса и должен вернуть набор результатов запроса Page (либо исходный, либо новый).
from wagtail import hooks
@hooks.register('construct_page_chooser_queryset')
def show_my_pages_only(pages, request):
# Only show own pages
pages = pages.filter(owner=request.user)
return pages
construct_document_chooser_queryset
Вызывается при отрисовке представления выбора документа, чтобы разрешить настройку набора результатов запроса списка документов. Вызываемый объект, переданный в обработчик, получит текущий набор результатов запроса документов и объект запроса и должен вернуть набор результатов запроса Document (либо исходный, либо новый).
from wagtail import hooks
@hooks.register('construct_document_chooser_queryset')
def show_my_uploaded_documents_only(documents, request):
# Only show uploaded documents
documents = documents.filter(uploaded_by_user=request.user)
return documents
construct_image_chooser_queryset
Вызывается при отрисовке представления выбора изображения, чтобы разрешить настройку набора результатов запроса списка изображений. Вызываемый объект, переданный в обработчик, получит текущий набор результатов запроса изображений и объект запроса и должен вернуть набор результатов запроса Image (либо исходный, либо новый).
from wagtail import hooks
@hooks.register('construct_image_chooser_queryset')
def show_my_uploaded_images_only(images, request):
# Only show uploaded images
images = images.filter(uploaded_by_user=request.user)
return images
Обзор страниц
construct_explorer_page_queryset
Вызывается при отрисовке представления обзора страниц, чтобы разрешить настройку набора результатов запроса списка страниц. Вызываемый объект, переданный в обработчик, получит родительский объект страницы, текущий набор результатов запроса страницы и объект запроса и должен вернуть набор результатов запроса Page (либо исходный, либо новый).
from wagtail import hooks
@hooks.register('construct_explorer_page_queryset')
def show_my_profile_only(parent_page, pages, request):
# If we're in the 'user-profiles' section, only show the user's own profile
if parent_page.slug == 'user-profiles':
pages = pages.filter(owner=request.user)
return pages
Отображение страниц
before_serve_page
Вызывается, когда Wagtail собирается отобразить страницу. Вызываемый объект, переданный в обработчик, получит объект страницы, объект запроса и args и kwargs, которые будут переданы методу serve() страницы. Если вызываемый объект возвращает HttpResponse, этот ответ будет немедленно возвращён пользователю, и Wagtail не будет вызывать метод serve() на странице.
from django.http import HttpResponse
from wagtail import hooks
@hooks.register('before_serve_page')
def block_googlebot(page, request, serve_args, serve_kwargs):
if request.META.get('HTTP_USER_AGENT') == 'GoogleBot':
return HttpResponse("<h1>bad googlebot no cookie</h1>")
Отображение документов
before_serve_document
Вызывается, когда Wagtail собирается отобразить документ. Вызываемый объект, переданный в обработчик, получит объект документа и объект запроса. Если вызываемый объект возвращает HttpResponse, этот ответ будет немедленно возвращён пользователю вместо отображения документа. Обратите внимание, что этот обработчик будет пропущен, если параметр WAGTAILDOCS_SERVE_METHOD установлен в значение direct.
Сниппеты
Крючки для работы со зарегистрированными Сниппетами.
after_edit_snippet
Вызывается при редактировании Сниппета. Переданная в крючок функция получит экземпляр модели и объект запроса. Если функция вернёт HttpResponse, этот ответ будет немедленно возвращён пользователю, и Wagtail не будет вызывать redirect() к представлению списка.
from django.http import HttpResponse
from wagtail import hooks
@hooks.register('after_edit_snippet')
def after_snippet_update(request, instance):
return HttpResponse(f"Congrats on editing a snippet with id {instance.pk}", content_type="text/plain")
before_edit_snippet
Вызывается в начале представления редактирования сниппета. Переданная в крючок функция получит экземпляр модели и объект запроса. Если функция вернёт HttpResponse, этот ответ будет немедленно возвращён пользователю, и Wagtail не будет вызывать redirect() к представлению списка.
from django.http import HttpResponse
from wagtail import hooks
@hooks.register('before_edit_snippet')
def block_snippet_edit(request, instance):
if isinstance(instance, RestrictedSnippet) and instance.prevent_edit:
return HttpResponse("Sorry, you can't edit this snippet", content_type="text/plain")
after_create_snippet
Вызывается при создании Сниппета. after_create_snippet и after_edit_snippet работают идентично. Единственное различие заключается в том, где вызывается крючок.
before_create_snippet
Вызывается в начале представления создания сниппета. Работает аналогично before_edit_snippet, за исключением того, что модель передаётся как аргумент вместо экземпляра.
after_delete_snippet
Вызывается при удалении Сниппета. Переданная в крючок функция получит экземпляр(ы) модели как набор запросов вместе с объектом запроса. Если функция вернёт HttpResponse, этот ответ будет немедленно возвращён пользователю, и Wagtail не будет вызывать redirect() к представлению списка.
from django.http import HttpResponse
from wagtail import hooks
@hooks.register('after_delete_snippet')
def after_snippet_delete(request, instances):
# "instances" is a QuerySet
total = len(instances)
return HttpResponse(f"{total} snippets have been deleted", content_type="text/plain")
before_delete_snippet
Вызывается в начале представления удаления сниппета. Переданная в крючок функция получит экземпляр(ы) модели как набор запросов вместе с объектом запроса. Если функция вернёт HttpResponse, этот ответ будет немедленно возвращён пользователю, и Wagtail не будет вызывать redirect() к представлению списка.
from django.http import HttpResponse
from wagtail import hooks
@hooks.register('before_delete_snippet')
def before_snippet_delete(request, instances):
# "instances" is a QuerySet
total = len(instances)
if request.method == 'POST':
# Override the deletion behaviour
instances.delete()
return HttpResponse(f"{total} snippets have been deleted", content_type="text/plain")
Массовые действия
Крючки для регистрации и настройки массовых действий. Смотрите Добавление пользовательских массовых действий, как написать пользовательские массовые действия.
register_bulk_action
Регистрирует новое массовое действие для добавления в список массовых действий в проводнике.
Этот крючок должен быть зарегистрирован с подклассом BulkAction. Например:
from wagtail.admin.views.bulk_action import BulkAction
from wagtail import hooks
@hooks.register("register_bulk_action")
class CustomBulkAction(BulkAction):
display_name = _("Custom Action")
action_type = "action"
aria_label = _("Do custom action")
template_name = "/path/to/template"
models = [...] # list of models the action should execute upon
@classmethod
def execute_action(cls, objects, **kwargs):
for object in objects:
do_something(object)
return num_parent_objects, num_child_objects # return the count of updated objects
before_bulk_action
Выполняет действия непосредственно перед выполнением массового действия (перед вызовом метода execute_action).
Этот крючок может быть использован для возврата ответа HTTP. Например:
from wagtail import hooks
@hooks.register("before_bulk_action")
def hook_func(request, action_type, objects, action_class_instance):
if action_type == 'delete':
return HttpResponse(f"{len(objects)} objects would be deleted", content_type="text/plain")
after_bulk_action
Выполняет действия непосредственно после выполнения массового действия (после вызова метода execute_action).
Этот крючок может быть использован для возврата ответа HTTP. Например:
from wagtail import hooks
@hooks.register("after_bulk_action")
def hook_func(request, action_type, objects, action_class_instance):
if action_type == 'delete':
return HttpResponse(f"{len(objects)} objects have been deleted", content_type="text/plain")
Журнал аудита
register_log_actions
См. Журнал аудита
Чтобы добавить новые действия в реестр, вызовите метод register_action с типом действия, его меткой и сообщением, которое будет отображаться в административных списках.
from django.utils.translation import gettext_lazy as _
from wagtail import hooks
@hooks.register('register_log_actions')
def additional_log_actions(actions):
actions.register_action('wagtail_package.echo', _('Echo'), _('Sent an echo'))
В качестве альтернативы, для сообщения журнала, которое варьируется в зависимости от данных записи журнала, создайте подкласс wagtail.log_actions.LogFormatter, который переопределяет метод format_message, и используйте register_action как декоратор на этом классе:
from django.utils.translation import gettext_lazy as _
from wagtail import hooks
from wagtail.log_actions import LogFormatter
@hooks.register('register_log_actions')
def additional_log_actions(actions):
@actions.register_action('wagtail_package.greet_audience')
class GreetingActionFormatter(LogFormatter):
label = _('Greet audience')
def format_message(self, log_entry):
return _('Hello %(audience)s') % {
'audience': log_entry.data['audience'],
}
Изменено в версии 2.15: Класс LogFormatter был представлен. Ранее динамические сообщения достигались путём передачи вызываемой функции в качестве аргумента message к register_action.
© 2014-present Torchbox Ltd and individual contributors.
All rights are reserved.
Licensed under the BSD License.
https://docs.wagtail.org/en/stable/reference/hooks.html