-
Notifications
You must be signed in to change notification settings - Fork 0
/
README.txt
52 lines (44 loc) · 5.15 KB
/
README.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
Комментарии:
Установка:
==========
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) Любые недопонимания исходного ТЗ могут быть более-менее легко исправлены/переделаны. Я специально не стал ничего уточнять по ТЗ.