Добавить в корзинуПозвонить
Найти в Дзене
Павлин Шарит

Пример кода большего проекта на джанго

Пример кода большего проекта на джанго Искал тут open-source альтернативы Jira — надоело работать с перегруженным интерфейсом и хочется больше контроля над системой. Среди вариантов наткнулся на Plane — довольно зрелый проект с чистым UI и всеми нужными фичами для project management Помимо самого функционала, Plane интересен как пример большого Django-проекта. Редко удается посмотреть на enterprise-решение изнутри — обычно такой код закрыт. А тут можно изучить архитектурные решения настоящей production-системы Где смотреть: - Основной репозиторий: https://github.com/makeplane/plane - Бэкенд: https://github.com/makeplane/plane/tree/preview/apps/api - Модели БД: /plane/db/models/ - API views: /plane/app/views/ Интересные решения, которые быстро нашел: PostgreSQL advisory locks для sequence generation def save(self, *args, **kwargs): if self._state.adding: with transaction.atomic(): lock_key = convert_uuid_to_integer(self.project.id) with connection.cursor() as cursor: cursor.execute

Пример кода большего проекта на джанго

Искал тут open-source альтернативы Jira — надоело работать с перегруженным интерфейсом и хочется больше контроля над системой. Среди вариантов наткнулся на Plane — довольно зрелый проект с чистым UI и всеми нужными фичами для project management

Помимо самого функционала, Plane интересен как пример большого Django-проекта. Редко удается посмотреть на enterprise-решение изнутри — обычно такой код закрыт. А тут можно изучить архитектурные решения настоящей production-системы

Где смотреть:

- Основной репозиторий: https://github.com/makeplane/plane

- Бэкенд: https://github.com/makeplane/plane/tree/preview/apps/api

- Модели БД: /plane/db/models/

- API views: /plane/app/views/

Интересные решения, которые быстро нашел:

PostgreSQL advisory locks для sequence generation

def save(self, *args, **kwargs):

if self._state.adding:

with transaction.atomic():

lock_key = convert_uuid_to_integer(self.project.id)

with connection.cursor() as cursor:

cursor.execute("SELECT pg_advisory_lock(%s)", [lock_key])

try:

last_sequence = IssueSequence.objects.filter(

project=self.project

).aggregate(largest=models.Max("sequence"))["largest"]

self.sequence_id = last_sequence + 1 if last_sequence else 1

# создание задачи и sequence записи

finally:

cursor.execute("SELECT pg_advisory_unlock(%s)", [lock_key])

Используют PostgreSQL advisory locks для генерации уникальных sequence_id задач без race conditions. Элегантнее чем SELECT FOR UPDATE и работает быстрее

Custom Manager с композитной фильтрацией

class IssueManager(SoftDeletionManager):

def get_queryset(self):

return (

super().get_queryset()

.filter(

models.Q(issue_intake__status=1)

| models.Q(issue_intake__status=-1)

| models.Q(issue_intake__status=2)

| models.Q(issue_intake__isnull=True)

)

.filter(deleted_at__isnull=True)

.filter(state__is_triage=False)

.exclude(archived_at__isnull=False)

.exclude(project__archived_at__isnull=False)

.exclude(is_draft=True)

)

На уровне менеджера исключают черновики, триаж, архивированные задачи и проекты. Логика скрыта от разработчиков — Issue.objects всегда возвращает только "настоящие" задачи

Динамическая система группировки с ArrayAgg

def issue_queryset_grouper(queryset, group_by, sub_group_by):

annotations_map = {

"assignee_ids": (

"assignees__id",

~Q(assignees__id__isnull=True) & Q(issue_assignee__deleted_at__isnull=True),

),

"label_ids": (

"labels__id",

~Q(labels__id__isnull=True) & Q(label_issue__deleted_at__isnull=True),

),

}

default_annotations = {

key: Coalesce(

ArrayAgg(field, distinct=True, filter=condition),

Value([], output_field=ArrayField(UUIDField())),

)

for key, (field, condition) in annotations_map.items()

if key not in [group_by, sub_group_by] # исключаем поля группировки

}

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

Plane — отличный пример того, как строить современные Django-приложения с нетривиальными требованиями к производительности и многотенантности. Код структурирован, есть интересные оптимизации и архитектурные решения

Поддержать на Boosty

Посмотреть на Youtube