feat: define core models
This commit is contained in:
parent
7dd8350cec
commit
4b4a85d1aa
|
@ -1,4 +1,86 @@
|
|||
from django.apps import AppConfig
|
||||
from django.db.models.signals import post_migrate
|
||||
|
||||
|
||||
def create_properties(sender, **kwargs):
|
||||
from .models import Property
|
||||
|
||||
Property.objects.get_or_create(
|
||||
name="Capacitance",
|
||||
defaults={
|
||||
"filterable": True,
|
||||
"type": Property.Type.QUANTITY,
|
||||
"unit": "F",
|
||||
"scale": -12,
|
||||
"searchable": False,
|
||||
},
|
||||
)
|
||||
|
||||
Property.objects.get_or_create(
|
||||
name="Footprint",
|
||||
defaults={
|
||||
"filterable": True,
|
||||
"type": Property.Type.TEXT,
|
||||
"unit": "",
|
||||
"scale": 0,
|
||||
"searchable": False,
|
||||
},
|
||||
)
|
||||
|
||||
Property.objects.get_or_create(
|
||||
name="LCSC part number",
|
||||
defaults={
|
||||
"filterable": False,
|
||||
"type": Property.Type.TEXT,
|
||||
"unit": "",
|
||||
"scale": 0,
|
||||
"searchable": True,
|
||||
},
|
||||
)
|
||||
|
||||
Property.objects.get_or_create(
|
||||
name="Inductance",
|
||||
defaults={
|
||||
"filterable": True,
|
||||
"type": Property.Type.QUANTITY,
|
||||
"unit": "H",
|
||||
"scale": -6,
|
||||
"searchable": False,
|
||||
},
|
||||
)
|
||||
|
||||
Property.objects.get_or_create(
|
||||
name="Rated power",
|
||||
defaults={
|
||||
"filterable": True,
|
||||
"type": Property.Type.QUANTITY,
|
||||
"unit": "W",
|
||||
"scale": -4,
|
||||
"searchable": False,
|
||||
},
|
||||
)
|
||||
|
||||
Property.objects.get_or_create(
|
||||
name="Rated voltage",
|
||||
defaults={
|
||||
"filterable": True,
|
||||
"type": Property.Type.QUANTITY,
|
||||
"unit": "V",
|
||||
"scale": -3,
|
||||
"searchable": False,
|
||||
},
|
||||
)
|
||||
|
||||
Property.objects.get_or_create(
|
||||
name="Resistance",
|
||||
defaults={
|
||||
"filterable": True,
|
||||
"type": Property.Type.QUANTITY,
|
||||
"unit": "Ω",
|
||||
"scale": -3,
|
||||
"searchable": False,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class CoreConfig(AppConfig):
|
||||
|
@ -6,3 +88,6 @@ class CoreConfig(AppConfig):
|
|||
label = "lelcsc_core"
|
||||
name = "lelcsc.core"
|
||||
verbose_name = "core"
|
||||
|
||||
def ready(self):
|
||||
post_migrate.connect(create_properties, sender=self)
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
# Generated by Django 5.1.1 on 2024-09-16 22:00
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("lelcsc_core", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="Component",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("part_number", models.CharField(max_length=30)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Property",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=50)),
|
||||
(
|
||||
"filterable",
|
||||
models.BooleanField(
|
||||
help_text="Whether this property can be used to filter components"
|
||||
),
|
||||
),
|
||||
(
|
||||
"type",
|
||||
models.CharField(
|
||||
choices=[("quantity", "Quantity"), ("text", "Text")],
|
||||
max_length=8,
|
||||
),
|
||||
),
|
||||
(
|
||||
"searchable",
|
||||
models.BooleanField(
|
||||
help_text="Whether this property should be used in search"
|
||||
),
|
||||
),
|
||||
(
|
||||
"unit",
|
||||
models.CharField(
|
||||
help_text="Symbol of this quantity's unit of measurement",
|
||||
max_length=3,
|
||||
),
|
||||
),
|
||||
(
|
||||
"scale",
|
||||
models.SmallIntegerField(
|
||||
help_text="Exponent of the smallest possible value"
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Stock",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("created_at", models.DateTimeField(auto_now_add=True)),
|
||||
("updated_at", models.DateTimeField(auto_now=True)),
|
||||
("quantity", models.PositiveIntegerField()),
|
||||
("original_quantity", models.PositiveIntegerField()),
|
||||
("total_value", models.DecimalField(decimal_places=2, max_digits=8)),
|
||||
("location", models.TextField()),
|
||||
("owner_name", models.CharField(max_length=150)),
|
||||
(
|
||||
"component",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.PROTECT,
|
||||
to="lelcsc_core.component",
|
||||
),
|
||||
),
|
||||
(
|
||||
"owner",
|
||||
models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"abstract": False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Value",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("text", models.TextField()),
|
||||
("integer", models.BigIntegerField()),
|
||||
(
|
||||
"component",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="lelcsc_core.component",
|
||||
),
|
||||
),
|
||||
(
|
||||
"property",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="lelcsc_core.property",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"unique_together": {("component", "property")},
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="component",
|
||||
name="properties",
|
||||
field=models.ManyToManyField(
|
||||
through="lelcsc_core.Value", to="lelcsc_core.property"
|
||||
),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,3 @@
|
|||
from .auth import OIDCUser, User
|
||||
from .component import Component, Property, Value
|
||||
from .stock import Stock
|
|
@ -0,0 +1,62 @@
|
|||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class Property(models.Model):
|
||||
class Type(models.TextChoices):
|
||||
QUANTITY = "quantity", _("Quantity")
|
||||
TEXT = "text", _("Text")
|
||||
|
||||
name = models.CharField(max_length=50)
|
||||
filterable = models.BooleanField(
|
||||
help_text=_("Whether this property can be used to filter components")
|
||||
)
|
||||
type = models.CharField(choices=Type, max_length=8)
|
||||
searchable = models.BooleanField(
|
||||
help_text=_("Whether this property should be used in search")
|
||||
)
|
||||
unit = models.CharField(
|
||||
max_length=3, help_text=_("Symbol of this quantity's unit of measurement")
|
||||
)
|
||||
scale = models.SmallIntegerField(
|
||||
help_text=_("Exponent of the smallest possible value")
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
self.name + f" [{self.unit}]" if self.type == Property.Type.QUANTITY else ""
|
||||
)
|
||||
|
||||
|
||||
class Component(models.Model):
|
||||
part_number = models.CharField(max_length=30)
|
||||
properties = models.ManyToManyField(Property, through="Value")
|
||||
|
||||
def __str__(self):
|
||||
return self.part_number
|
||||
|
||||
|
||||
class Value(models.Model):
|
||||
class Meta:
|
||||
unique_together = ("component", "property")
|
||||
|
||||
property = models.ForeignKey(Property, on_delete=models.CASCADE)
|
||||
component = models.ForeignKey(Component, on_delete=models.CASCADE)
|
||||
text = models.TextField()
|
||||
integer = models.BigIntegerField()
|
||||
|
||||
def __str__(self):
|
||||
match self.property.type:
|
||||
case Property.Type.QUANTITY:
|
||||
s = str(integer)
|
||||
|
||||
scale = self.property.scale
|
||||
if scale > 0:
|
||||
s += "0" * scale
|
||||
elif scale < 0:
|
||||
s = str(integer).rjust(abs(scale) + 1, "0")
|
||||
s = s[:scale] + "." + s[scale:]
|
||||
|
||||
return f"{s} {self.property.unit}"
|
||||
case Property.Type.TEXT:
|
||||
return self.text
|
|
@ -0,0 +1,9 @@
|
|||
from django.db import models
|
||||
|
||||
|
||||
class HasTimestamps(models.Model):
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
|
@ -0,0 +1,15 @@
|
|||
from django.db import models
|
||||
|
||||
from .auth import User
|
||||
from .component import Component
|
||||
from .mixins import HasTimestamps
|
||||
|
||||
|
||||
class Stock(HasTimestamps):
|
||||
component = models.ForeignKey(Component, on_delete=models.PROTECT)
|
||||
quantity = models.PositiveIntegerField()
|
||||
original_quantity = models.PositiveIntegerField()
|
||||
total_value = models.DecimalField(max_digits=8, decimal_places=2)
|
||||
location = models.TextField()
|
||||
owner = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
|
||||
owner_name = models.CharField(max_length=150)
|
Loading…
Reference in New Issue