Суть проблемы
Существует модель данных, вида `Organization` <- (fk) `Project` <- (fk) `Resource`. Когда юзер выбирает организацию в шапке, то попадает на detail view, например "/organization/1/details/". Теперь нужно, чтобы все ссылки на проекты и ресурсы (например, в сайдбаре) отображали только связанную с выбранной организацией информацию, т.е. к queryset добавлялся бы фильтр, типа
qs &= Q(project__organization=organization_id)
UPD1То есть, выбор проекта, или организации - это на самом деле смена текущего контекста отображения. В контексте выбранной организации все ссылки ведут только на проекты для этой организации, и т.д.
Как я пробовал это делать
1.
Опциональные аргументы в urlsurl(r'^(?:organization/(?P<organization_id>\d+)/)?projects/$', 'app.views.projects', name='projects'),
url(r'^(?:organization/(?P<organization_id>\d+)/)?(?:project/(?P<project_id>\d+)/)?resources/$', 'app.views.resources', name='resources'),
Этот метод требует, во-первых, переписывания всех ссылок в шаблонах.
`{% url 'projects' org.id %}`
`{% url 'resources' org.id prj.id %}`
Во-вторых, есть проблема с постоянной передачей organization_id (filter_field) в шаблоны. Эту проблему сравнительно просто можно решить при помощи middleware, например, так:
class FetchFiltersMiddleware(object):
def process_view(self, request, view_func, view_args, view_kwargs):
request.project_id = view_kwargs.get('project_id', 0) # или .pop(), тогда не надо переписывать аргументы вьюх
request.organization_id = view_kwargs.get('organization_id', 0)
Попутно можно написать context_processor, который поместит все нужное в контекст (на случай, если request не попадает в шаблоны).
Конечно, остальные не переписанные ссылки будут работать так же, как и раньше, но будут ломать навигацию, потому что параметры фильтрации (organization_id, project_id, etc) постоянно должны присутствовать в url, иначе они "потеряются". Например, редактирование профиля пользователя не должно содержать этих фильтров. Поэтому у этого метода следующие минусы:
- модификация всех {% url %}, или намеренное сокрытие ссылок, которые сломают навигацию, что усложнит жизнь пользователям
- сильное усложнение urls.py
- дополнительные накладные расходы на написание кода, проверяющего наличие фильтров
2.
COOKIE, или GET
GET - метод, который испортит "красоту" url; COOKIE я пока не пробовал, но всячески избегаю их использования.
3.
Хранение текущего фильтра в сессии, или в кэше.
Метод легко использовать, но он плох тем, что открытие сайта на другой вкладке испортит навигацию на первой вкладе.
4.
Full-ajax навигация + переписывание нужных ссылок, например при помощи Django.js.url.
Overkill.
У меня кончились идеи.