Skip to content

776166/menu

Repository files navigation

Комментарии:

Установка:
==========
1) Добавить в settings:
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
    }
}
2) INSTALLED_APPS += [
    'menu',
]

Производительность
==================
1) Исходя из задания я понял, что система должна быть максимально производительной и не нагружать базу. Потому сделал некоторые специальные действия для этого (которые ужже очень давно хотел попробовать).
2) Параметры пунктов меню вычисляются при изменениях и записываются в базу (поля *_cached). Любые качественные изменения приводят к перерассчёту этих параметров для изменяемой ветки и каскадному перерасчёту для всего дерева вверх).


Неявная логика работы
=====================
1) Меню основывается на простых урлах типа /foo/bar/baz/.
2) Именованные урлы и внешние ссылки задаются отдельными полями.
    — Приоритеты: именованный > внешнего > полный slug
    — Если они пустые, то рабочим урлом считается полный вычисленный slug.
    — Если именованный урл не задан при заданном внешнем урле, то используется внешний url.
    — Если задан именованный url, то он проверяется на валидность. Если валидный, то используется он. Если нет, то при наличии внешнего url, внешний, если нет, то полный вычисленный slug.
    — При перезапуске приложения, именованные урлы не перерасчитываются. Просто не стал делать, хотя это и не очень корректно, но пишу об этом здесь.

Рендер меню
===========
1) Если для {% draw_menu 'foo' %} указывается некорректное имя меню ('foo'), то возвращается None.
2) Меню рендерится в виде последовательных дивов со следующими параметрами:
    — CSS class 'open': пункт меню открыт
    — CSS class 'active': текущий пункт меню (совпадает с url)
    — Параметр тэга data-branch_level: уровнь вложенности пункта меню.
    
    Для казуальной наглядности в шаблоне имеется принудительный отступ, но вообще, это не очень корректно и это нужно делать уже на клиенте.
    Меню рендерится по шаблону. Сообветственно, его можно менять.
3) Рендер меню осуществляется за один запрос к базе. В худшем случае. Устроено так, что рендер работает с одним общим запросом веток, который фильтруется, а сам запрос складывается в кеш (в памяти), который обнуляется при изменениях ветки меню и пересоздаётся при следующем запросе.

Известные баги и 2DO
====================
1) В какой-то момент выяснилось, что меню не поддерживает нулевой уровень вложенности (/). Допиливать уже не стал, это ничего принципиально не меняет, только добавляет лишнюю сложность с проверкой на уникальность. НЕ вижу в этом особого смысла в рамках этого тестового задания.
2) Тетсирование не охватывает именованные урлы. С ходу не получилось добавлять ROOT_URLCONF урлы для тестирования. Думаю, с этим можно разобраться.
3) Именованные урлы поддерживаются только для базового приложения (регулярка). Должно расширяться без особых проблем.

Разное
======
1) Не стал оформлять полноценной документацией, так как не вижу особого смысла тратить время.
2) Любые недопонимания исходного ТЗ могут быть более-менее легко исправлены/переделаны. Я специально не стал ничего уточнять по ТЗ.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published