Portal/rsconcept/backend/apps/library/models/Editor.py
Ivan 31195cdd60
Some checks failed
Backend CI / build (3.12) (push) Has been cancelled
Frontend CI / build (22.x) (push) Has been cancelled
R: Improve backend type hints, linting and package locks
2024-09-12 21:10:05 +03:00

92 lines
2.8 KiB
Python

''' Models: Editor. '''
from typing import Iterable
from django.db import transaction
from django.db.models import CASCADE, DateTimeField, ForeignKey, Model
from apps.users.models import User
class Editor(Model):
''' Editor list. '''
item = ForeignKey(
verbose_name='Схема',
to='library.LibraryItem',
on_delete=CASCADE
)
editor = ForeignKey(
verbose_name='Редактор',
to=User,
on_delete=CASCADE
)
time_create = DateTimeField(
verbose_name='Дата добавления',
auto_now_add=True
)
class Meta:
''' Model metadata. '''
verbose_name = 'Редактор'
verbose_name_plural = 'Редакторы'
unique_together = [['item', 'editor']]
def __str__(self) -> str:
return f'{self.item}: {self.editor}'
@staticmethod
def add(item: int, user: int) -> bool:
''' Add Editor for item. '''
if Editor.objects.filter(item_id=item, editor_id=user).exists():
return False
Editor.objects.create(item_id=item, editor_id=user)
return True
@staticmethod
def remove(item: int, user: int) -> bool:
''' Remove Editor. '''
editor = Editor.objects.filter(item_id=item, editor_id=user).only('pk')
if not editor.exists():
return False
editor.delete()
return True
@staticmethod
@transaction.atomic
def set(item: int, users: Iterable[int]):
''' Set editors for item. '''
processed: set[int] = set()
for editor_item in Editor.objects.filter(item_id=item).only('editor_id'):
editor_id = editor_item.editor_id
if editor_id not in users:
editor_item.delete()
else:
processed.add(editor_id)
for user in users:
if user not in processed:
processed.add(user)
Editor.objects.create(item_id=item, editor_id=user)
@staticmethod
@transaction.atomic
def set_and_return_diff(item: int, users: Iterable[int]) -> tuple[list[int], list[int]]:
''' Set editors for item and return diff. '''
processed: list[int] = []
deleted: list[int] = []
added: list[int] = []
for editor_item in Editor.objects.filter(item_id=item).only('editor_id'):
editor_id = editor_item.editor_id
if editor_id not in users:
deleted.append(editor_id)
editor_item.delete()
else:
processed.append(editor_id)
for user in users:
if user not in processed:
processed.append(user)
added.append(user)
Editor.objects.create(item_id=item, editor_id=user)
return (added, deleted)