from django.contrib.auth.forms import gettext as _ from django.db import models from app.utils.models import BaseModel from users.models import UserSettings class ItemBase(BaseModel): class Meta: abstract = True class Serialization(BaseModel.Serialization): excluded_fields = BaseModel.Serialization.excluded_fields + ["author"] excluded_fields_edit = BaseModel.Serialization.excluded_fields_edit + ["author"] author = models.ForeignKey(UserSettings, on_delete=models.PROTECT) class ItemType(ItemBase): pass class ItemRelation(ItemBase): parent = models.ForeignKey("items.Item", on_delete=models.CASCADE, related_name="children") child = models.ForeignKey("items.Item", on_delete=models.CASCADE, related_name="parents") properties = models.ManyToManyField("items.Property", through="items.RelationProperty", related_name="relations") class Item(ItemBase): name = models.TextField(max_length=2048) description = models.TextField(max_length=2048) type = models.ForeignKey(ItemType, on_delete=models.PROTECT) relations = models.ManyToManyField( "items.Item", through=ItemRelation, ) properties = models.ManyToManyField( "items.Property", through="LinkedProperty", related_name="items", ) class PropertyType(models.TextChoices): TEXT = "text", _("Text") DATE = "date", _("Date") DATETIME = "datetime", _("Date & time") TIME = "time", _("Time") DURATION = "duration", _("Duration") UUID = "uuid", _("UUID") NUMBER = "number", _("Number") FLOAT = "float", _("Float") BOOLEAN = "boolean", _("Boolean") EMAIL = "email", _("Email") IP = "ip", _("IP address") JSON = "json", _("JSON") # TODO: Add more property types (location, etc) class Property(ItemBase): type = models.CharField(max_length=32, choices=PropertyType.choices, default=PropertyType.TEXT) class BaseLinkedProperty(ItemBase): class Meta: abstract = True property = models.ForeignKey(Property, on_delete=models.CASCADE) # Value is encrypted too value = models.TextField(max_length=2048) class LinkedProperty(BaseLinkedProperty): item = models.ForeignKey(Item, on_delete=models.CASCADE, null=True, related_name="linked_properties") class RelationProperty(BaseLinkedProperty): relation = models.ForeignKey( ItemRelation, on_delete=models.CASCADE, null=True, related_name="relation_properties", )