Инфраструктура: Celery, общие утилиты, виджеты, шелл портала

- acore: Celery-приложение (брокер из env, eager без брокера), настройки
  CELERY_*, регистрация всех новых приложений в INSTALLED_APPS, маршруты
- core/utils: render_page (HTMX-фрагмент/полный layout), is_owner/
  is_owner_or_staff; templatetags common_tags (initials, clean_excerpt,
  is_it_staff); UpdateLastSeenMiddleware
- static: people-picker (дерево отделов с аватарками), searchable-select
  (одиночный выбор с поиском), directory-quick-add, it-manager, pagination;
  тема Tailwind v4 пересобрана, лого
- templates: новый шелл index.html (мобильный сайдбар, темы, фон,
  user-dropdown) и login с брендингом

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 17:31:01 +03:00
parent c3f56f8a3e
commit 78475b58e9
22 changed files with 2996 additions and 22 deletions
+15
View File
@@ -0,0 +1,15 @@
from django.shortcuts import render
def is_htmx_request(request) -> bool:
"""Запрос прислан HTMX (hx-get/hx-post), а не обычной навигацией браузера"""
return request.headers.get('HX-Request') == 'true'
def render_page(request, page_template: str, context: dict = None):
"""Страница портала: HTMX-фрагмент из pages/<page_template> или полный
layout (index.html) с этим же фрагментом внутри — по типу запроса."""
context = context or {}
if is_htmx_request(request):
return render(request, f'pages/{page_template}', context)
return render(request, 'index.html', {'page_template': f'pages/{page_template}', **context})
+8
View File
@@ -0,0 +1,8 @@
def is_owner_or_staff(user, obj, owner_field: str = 'author_id') -> bool:
"""Редактировать может администратор (is_staff) или владелец объекта"""
return user.is_staff or getattr(obj, owner_field) == user.pk
def is_owner(user, obj, owner_field: str = 'author_id') -> bool:
"""Удалять с портала может только владелец (staff — через админку)"""
return getattr(obj, owner_field) == user.pk