toolshed/backend/toolshed/models.py
jedi 8cf0897ec5
All checks were successful
continuous-integration/drone/push Build is passing
make dataset parsing more robust
2024-03-16 19:58:22 +01:00

122 lines
5.5 KiB
Python

from django.db import models
from django.core.validators import MinValueValidator
from django_softdelete.models import SoftDeleteModel
from rest_framework.exceptions import ValidationError
from authentication.models import ToolshedUser, KnownIdentity
from files.models import File
class Category(SoftDeleteModel):
name = models.CharField(max_length=255)
description = models.TextField(null=True, blank=True)
parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, related_name='children')
origin = models.CharField(max_length=255, null=False, blank=False)
class Meta:
verbose_name_plural = 'categories'
constraints = [
models.UniqueConstraint(fields=['name', 'parent'], condition=models.Q(parent__isnull=False),
name='category_unique_name_parent'),
models.UniqueConstraint(fields=['name'], condition=models.Q(parent__isnull=True),
name='category_unique_name_no_parent')
]
def __str__(self):
parent = str(self.parent) + "/" if self.parent else ""
return parent + self.name
class Property(models.Model):
name = models.CharField(max_length=255)
description = models.TextField(null=True, blank=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, related_name='properties')
unit_symbol = models.CharField(max_length=16, null=True, blank=True)
unit_name = models.CharField(max_length=255, null=True, blank=True)
unit_name_plural = models.CharField(max_length=255, null=True, blank=True)
base2_prefix = models.BooleanField(default=False)
dimensions = models.IntegerField(null=False, blank=False, default=1, validators=[MinValueValidator(1)])
origin = models.CharField(max_length=255, null=False, blank=False)
class Meta:
verbose_name_plural = 'properties'
constraints = [
models.UniqueConstraint(fields=['name', 'category'], condition=models.Q(category__isnull=False),
name='property_unique_name_category'),
models.UniqueConstraint(fields=['name'], condition=models.Q(category__isnull=True),
name='property_unique_name_no_category')
]
def __str__(self):
return self.name
class Tag(models.Model):
name = models.CharField(max_length=255)
description = models.TextField(null=True, blank=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, related_name='tags')
origin = models.CharField(max_length=255, null=False, blank=False)
class Meta:
verbose_name_plural = 'tags'
constraints = [
models.UniqueConstraint(fields=['name', 'category'], condition=models.Q(category__isnull=False),
name='tag_unique_name_category'),
models.UniqueConstraint(fields=['name'], condition=models.Q(category__isnull=True),
name='tag_unique_name_no_category')
]
def __str__(self):
return self.name
class InventoryItem(SoftDeleteModel):
AVAILABILITY_POLICY_CHOICES = (
('sell', 'Sell'),
('rent', 'Rent'),
('lend', 'Lend'),
('share', 'Share'),
('private', 'Private'),
)
published = models.BooleanField(default=False)
name = models.CharField(max_length=255, null=True, blank=True)
description = models.TextField(null=True, blank=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, related_name='inventory_items')
availability_policy = models.CharField(max_length=20, choices=AVAILABILITY_POLICY_CHOICES, default='private')
owned_quantity = models.IntegerField(default=1, validators=[MinValueValidator(0)])
owner = models.ForeignKey(ToolshedUser, on_delete=models.CASCADE, related_name='inventory_items')
created_at = models.DateTimeField(auto_now_add=True)
tags = models.ManyToManyField(Tag, through='ItemTag', related_name='inventory_items')
properties = models.ManyToManyField(Property, through='ItemProperty')
files = models.ManyToManyField(File, related_name='connected_items')
storage_location = models.ForeignKey('StorageLocation', on_delete=models.CASCADE, null=True, blank=True,
related_name='inventory_items')
def clean(self):
if (self.name is None or self.name == "") and self.files.count() == 0:
raise ValidationError("Name or at least one file must be set")
class ItemProperty(models.Model):
property = models.ForeignKey(Property, on_delete=models.CASCADE)
inventory_item = models.ForeignKey(InventoryItem, on_delete=models.CASCADE)
value = models.CharField(max_length=255)
class ItemTag(models.Model):
tag = models.ForeignKey(Tag, on_delete=models.CASCADE)
inventory_item = models.ForeignKey(InventoryItem, on_delete=models.CASCADE)
class StorageLocation(models.Model):
name = models.CharField(max_length=255)
description = models.TextField(null=True, blank=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True,
related_name='storage_locations')
parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
owner = models.ForeignKey(ToolshedUser, on_delete=models.CASCADE, related_name='storage_locations')
def __str__(self):
parent = str(self.parent) + "/" if self.parent else ""
return parent + self.name