Как стать автором
Поиск
Написать публикацию
Обновить

Как устроен пакет Django-Leaflet-Admin-List

Уровень сложностиПростой
Время на прочтение4 мин
Количество просмотров1K

Попросили рассказать про этот пакет, чем я и займусь.

Для чего нужен пакет

Django позволяет хранить и отображать географические поля. Если вы откроете админку объекта, в котором есть географическое поле, вы увидите участок карты с размещенными на ней геометрическими деталями - точкой, линией, полигоном или даже все это вместе, в зависимости от типа поля.

Редактирование объекта с геополем в админке Django
Редактирование объекта с геополем в админке Django

Однако, открыв стандартный список объектов в админке, вы не увидите их географического отображения. Их относительное расположение, группировка по географическим пунктам и прочие детали их географии, остаются для вас нераскрытыми, пока вы не заглянули на отдельную страницу редактирования объекта.

Чтобы исправить этот недостаток, был придуман пакет django-leaflet-admin-list. Он отображает все объекты из страницы списка на общей карте, размещенной сверху списка.

Список геообъектов в админке, модифицированный с помощью пакета Django-Leaflet-Admin-List
Список геообъектов в админке, модифицированный с помощью пакета Django-Leaflet-Admin-List

Теперь взаимное расположение двух зданий на карте вполне очевидно сразу при просмотре списка зданий, без необходимости открывать каждый объект и смотреть их по отдельности.

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

Как пользоваться

Пакет устанавливается из хранилища PyPi. После установки, включите пакет (рекомендую также использовать пакет django-leaflet для сохранения единого визуального стиля, хотя это не обязательно) в список используемых пакетов в файле settings.py, как это обычно делается для проекта Django:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    ...
    'leaflet',
    'leaflet_admin_list',
    ...
]

Используйте LeafletAdminListMixin в качестве одного из базовых классов для админки вашей географической модели:

...
from leaflet_admin_list.admin import LeafletAdminListMixin
...

class BuildingAdmin(LeafletAdminListMixin, ModelAdmin):
...

Админка модели может использовать пакет django-leaflet одновременно с пакетом django-leaflet-admin-list:

...
from leaflet.admin import LeafletGeoAdminMixin
from leaflet_admin_list.admin import LeafletAdminListMixin
...

class BuildingAdmin(LeafletAdminListMixin, LeafletGeoAdminMixin, ModelAdmin):
...

Теперь список объектов модели Building в админке будет отображаться с картой, на которой будут отображены все объекты, попавшие на страницу.

Кастомизация объектов на карте

Объекты на карте отображаются с помощью GeoJSON, загружаемого прямо на страницу при ее рендеринге, в виде части кода JavaScript. Содержимое отображаемого GeoJSON формируется методом миксина get_geojson_feature_list. Тот, в свою очередь, вызывает другие методы миксина, каждый из которых можно перекрыть собственной реализацией. Стек вызовов методов выглядит следующим образом:

  • get_geojson_feature_list

    • get_geojson_features

      • get_geojson_geometry_fields

      • get_geojson_feature

        • get_geojson_geometry

        • get_geojson_properties

          • get_geojson_feature_popup

          • get_geojson_feature_tooltip

            • get_geojson_feature_verbose_name

          • get_geojson_feature_point_style

            • get_geojson_feature_icon_style

          • get_geojson_feature_line_style

Финальный формат возвращаемого объекта полностью соответствует стандартному GeoJSON, который используется в вызове конструктора L.GeoJSON библиотеки LeafletJS. Все свойства передаются через атрибут properties соответствующих географических объектов GeoJSON и обрабатываются кодом JavaScript, превращаясь в соответствующие графические элементы с помощью обратных вызовов.

Посмотрим, как мы можем изменить отображение географических объектов.

Попробуем согласно документации LeafletJS, изменить цвет линий и заполнения на ярко-зеленый и темно-зеленый соответственно. Обратите внимание, что я сделал фон полностью непрозрачным, чтобы цвет был виден лучше.

class BuildingAdmin(LeafletAdminListMixin, LeafletGeoAdminMixin, ModelAdmin):
    ...
    def get_geojson_feature_line_style(self, request, name, o, queryset):
        return {
            'color': '#00F000',
            'fillColor': '#00A000',
            'fillOpacity': 1.0,
        }
Кастомизация цвета линии и подложки
Кастомизация цвета линии и подложки

Теперь исправим иконки, обозначающие подъезды у зданий. Сделаем их крохотными кружочками, центрированными по координатам точек

class BuildingAdmin(LeafletAdminListMixin, LeafletGeoAdminMixin, ModelAdmin):
    ...

    def get_geojson_feature_line_style(self, request, name, o, queryset):
        return {
            'color': '#00F000',
            'fillColor': '#00A000',
            'fillOpacity': 1.0,
        }

    def get_geojson_feature_icon_style(self, request, name, o, queryset):
        return {
            'iconUrl': 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+PHN2ZyBpZD0iTGF5ZXJfMV8xXyIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTYgMTY7IiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g
            'iconSize': [5, 5],
            'iconAnchor': [3, 3]
        }

И посмотрим на результат.

Кастомизация иконки
Кастомизация иконки

Тем же способом, вы можете кастомизировать все аспекты отображения ваших географических объектов, вплоть до того, чтобы самому сгенерировать GeoJSON полностью.

Перекрывая методы, вы можете полностью контролировать вывод объектов на карту, в зависимости от параметров вызовов:

  • request - запрос HTTP

  • queryset - список объектов модели, подлежащих выводу в соответствие с параметрами постраничной разбивки

  • o - объект модели

  • name - имя поля

Например, вы можете:

  • добавлять свои объекты на карту (допустим, вы хотели бы отображать текущее местоположение пользователя)

  • игнорировать отдельные объекты, не выводя их на карту (например, желая скрыть географическую информацию о них)

  • анализировать негеографические поля объекта и применять разные стили в зависимости от них (например, менять цвет линий и фона многоугольников в зависимости от типа или статуса объекта, использовать разные иконки для точек и т.д.)

  • анализировать, какое именно поле выводится, чтобы выводить разные поля разными стилями (например, выделяя конструктивные элементы объекта, прилежащую территорию, и т.п.)

Заключение

Использование пакета регулируется лицензией открытого кода LGPL. Поделитесь здесь своим опытом использования пакета, присоединяйтесь к его разработке на GitHub, предлагая новые свойства и готовые исправления для общей пользы.

Теги:
Хабы:
0
Комментарии0

Публикации

Ближайшие события