Card (Карточка)¶
Представляют собой ReadOnly (без возможности редактирования) пользовательский интерфейс состоящий из статичных HTML страниц.
В основе которого шаблонизатор Jinja и класс-генератор данных для environment.
Обладает следующими преимуществами по сравнению с базовым интерфейсом пользователья:
- Предназначен только для чтения
- Более высокая скорость отрисовки
- Работает даже на очень старых версиях браузеров
- Благодаря доступность черезе
URLпозволяет организовать обмен ссылками
Базовой директории является <noc>/services/card/, представляет собой следующую структуру:
services/
└──card
├── cards
└── templates
└── translations
├── pt_BR
└── ru
В директориях представлено следующее содержимое:
- cards бэкэнд генератор переменных для
environmentшаблонизатора - templates Шаблон HTML для формирования страницы карточки. Файл с расширением
<template_name>.html.j2 - translations - строки перевода
Note
Для простоты дальше по тексту бэкэнд карточки будем называть карточка
Файл карточки¶
Базовый класс карточки - BaseCard расположен в файле cards/base.py, карточки должны наследовать от него.
Обязательными к реализации является метод get_data, возвращающий набор переменных для использования в шаблоне страницы
и заполнение аттрибутов name - имя карточки (должно быть уникальным) и default_template_name - имя шаблона карточки,
model - ссылка на модель данных с которой работает карточка.
Для вызова карточки формируется URL вида <root>/<card_name>/<ID>/, где:
<root>- базовый URL НОКа<card_name>- имя карточки, указанное в аттрибутеname<ID>- идентификатор запрашиваемых данных, в случае заполненногоmodel, будет произведён поиск инстанса по идентификатору. Если поиск не удался - будет выдана страницаNot Found
Полезные методы класса BaseCard:
get_object- в нём происходит поиск переданного<ID>, может быть полезно переопределить если необходим поиск по нескольким идентификаторамRedirectError- класс ошибки делает переадресацию на заданныйURLNotFoundError- возвращает страницу404. По умолчанию открывается если не удалось найти объект по идентификатору<ID>
Пример простой карточки по модели Firmware, в качестве данных возвращается инстанс Firmware
Файл карточки:
from noc.inv.models.firmware import Firmware
from .base import BaseCard # Базовый класс
class FirmwarePlanCard(BaseCard):
name = "firmware" # Имя карточки
default_template_name = "firmware" # Имя шаблона по умолчанию
model = Firmware # Ссылка на модель
def get_data(self): # Формирование данных для шаблонизатора
# return {"object": self.object}
...
Как видно в данной карточке выводится информация о конкретном инстансе. Это часто встречающаяся использование карточек.
Рассмотрим несколько особых случаев использования карточек
Карточки без модели данных¶
Помимо карточек с данными какой-либо модели, могут быть реализованы карточки не связанные с данными какой-либо конкретной модели. В этом случае аттрибут model не заполняется. Примерами таких карточек являются outage и path.
Карточка path вывод на географическую карту путь между парой ManagedObject
class PathCard(BaseCard):
name = "path"
default_template_name = "path"
card_css = ["/ui/pkg/leaflet/leaflet.css", "/ui/card/css/path.css"]
card_js = ["/ui/pkg/leaflet/leaflet.js", "/ui/card/js/path.js"]
def get_data(self):
...
return {"mo1": mo1, "mo2": mo2, "path": smart_text(orjson.dumps(path))}
На примере можно видеть использование библиотеки leaflet для отрисовки географической карты в дополнение модуля path реализующего функционал в JavaScript.
Карточки реализованные через Ajax¶
В некоторых случаях есть необходимость формировать динамическое наполнение через API вместо формирования статического HTML. В этом случае отдаваемые данные формируются через метод get_ajax_data. Примером такой карточки служит alarmheat - cards/alarmheat.py:
class AlarmHeatCard(BaseCard):
name = "alarmheat"
card_css = ["/ui/pkg/leaflet/leaflet.css", "/ui/card/css/alarmheat.css"]
card_js = [
"/ui/pkg/leaflet/leaflet.js",
"/ui/pkg/leaflet.heat/leaflet-heat.js",
"/ui/card/js/alarmheat.js",
]
default_template_name = "alarmheat"
_layer_cache = {}
TOOLTIP_LIMIT = config.card.alarmheat_tooltip_limit
def get_data(self):
return {
"maintenance": 0,
"lon": self.current_user.heatmap_lon or 0,
"lat": self.current_user.heatmap_lat or 0,
"zoom": self.current_user.heatmap_zoom or 0,
}
def get_ajax_data(self, **kwargs):
zoom = int(self.handler.get_argument("z"))
west = float(self.handler.get_argument("w"))
east = float(self.handler.get_argument("e"))
...
return {
"alarms": alarms,
"summary": self.f_glyph_summary({"service": services, "subscriber": subscribers}),
"links": links,
"pops": points,
}
В данной карточке реализован метод get_ajax_data, и доступ к аргументам непосредственно из метода формирования данных.