94 lines
3.2 KiB
Python
94 lines
3.2 KiB
Python
from django.contrib.contenttypes.fields import GenericForeignKey
|
||
from django.contrib.contenttypes.models import ContentType
|
||
from django.db import models
|
||
from django.db.models import Q
|
||
|
||
|
||
class CalendarBinding(models.Model):
|
||
class BindingType(models.TextChoices):
|
||
DEFAULT = "default", "Обычный"
|
||
DEPARTMENT = "department", "Отдел"
|
||
|
||
class AccessScope(models.TextChoices):
|
||
RESTRICTED = "restricted", "Только участники"
|
||
ALL = "all", "Вся компания"
|
||
|
||
calendar = models.OneToOneField(
|
||
"schedule.Calendar",
|
||
on_delete=models.CASCADE,
|
||
related_name="binding",
|
||
verbose_name="Календарь",
|
||
)
|
||
type = models.CharField(
|
||
max_length=32,
|
||
choices=BindingType.choices,
|
||
default=BindingType.DEFAULT,
|
||
db_index=True,
|
||
verbose_name="Тип привязки",
|
||
)
|
||
access_scope = models.CharField(
|
||
max_length=16,
|
||
choices=AccessScope.choices,
|
||
default=AccessScope.RESTRICTED,
|
||
db_index=True,
|
||
verbose_name="Доступ",
|
||
)
|
||
context_content_type = models.ForeignKey(
|
||
ContentType,
|
||
null=True,
|
||
blank=True,
|
||
on_delete=models.CASCADE,
|
||
verbose_name="Тип контекста",
|
||
)
|
||
context_object_id = models.PositiveIntegerField(
|
||
null=True,
|
||
blank=True,
|
||
verbose_name="ID объекта контекста",
|
||
)
|
||
context_object = GenericForeignKey(
|
||
"context_content_type",
|
||
"context_object_id",
|
||
)
|
||
flags = models.JSONField(default=dict, blank=True, verbose_name="Флаги")
|
||
extra_data = models.JSONField(default=dict, blank=True, verbose_name="Доп. данные")
|
||
notify_event_created = models.BooleanField(
|
||
default=True,
|
||
verbose_name="Уведомлять о создании события",
|
||
)
|
||
notify_event_changed = models.BooleanField(
|
||
default=True,
|
||
verbose_name="Уведомлять об изменении события",
|
||
)
|
||
notify_event_cancelled = models.BooleanField(
|
||
default=True,
|
||
verbose_name="Уведомлять об удалении события",
|
||
)
|
||
created_at = models.DateTimeField(auto_now_add=True)
|
||
updated_at = models.DateTimeField(auto_now=True)
|
||
|
||
class Meta:
|
||
verbose_name = "Привязка календаря"
|
||
verbose_name_plural = "Привязки календарей"
|
||
constraints = [
|
||
models.UniqueConstraint(
|
||
fields=["type", "context_content_type", "context_object_id"],
|
||
condition=Q(
|
||
type="department",
|
||
context_content_type__isnull=False,
|
||
context_object_id__isnull=False,
|
||
),
|
||
name="uniq_department_calendar_binding",
|
||
),
|
||
]
|
||
indexes = [
|
||
models.Index(fields=["type"], name="calendar_binding_type_idx"),
|
||
models.Index(
|
||
fields=["context_content_type", "context_object_id"],
|
||
name="calendar_binding_context_idx",
|
||
),
|
||
]
|
||
|
||
def __str__(self) -> str:
|
||
target = self.context_object or self.calendar
|
||
return f"{self.type}: {target}"
|