109 lines
3.0 KiB
Python
109 lines
3.0 KiB
Python
from django.contrib.auth.forms import gettext as _
|
|
from django.db import models
|
|
|
|
|
|
from app.utils.models import BaseModel
|
|
from users.models import UserSettings
|
|
|
|
|
|
from simple_history.models import HistoricalRecords
|
|
|
|
|
|
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)
|
|
history = HistoricalRecords(inherit=True, user_model=UserSettings)
|
|
|
|
@property
|
|
def _history_user(self):
|
|
return self.author
|
|
|
|
@_history_user.setter
|
|
def _history_user(self, value):
|
|
self.author = value
|
|
|
|
|
|
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")
|
|
IPV4 = "ipv4", _("IPv4 address")
|
|
IPV6 = "ipv6", _("IPv6 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
|
|
|
|
class Serialization(ItemBase.Serialization):
|
|
dynamic_field_type = ItemBase.Serialization.dynamic_field_type + ["value"]
|
|
|
|
class Encryption(ItemBase.Encryption):
|
|
fields = ItemBase.Encryption.fields + ["value"]
|
|
|
|
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",
|
|
)
|