K356/k356/items/models.py

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.PROTECT)
# 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",
)