2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-03-15 08:33:42 +00:00

More migration updates:

- Create new "models" (without moving the existing tables)
- Data migration for PartCataegoryParameterTemplate model
- Remove PartParameterTemplate and PartParameter models
This commit is contained in:
Oliver Walters
2025-12-03 12:04:38 +00:00
parent 9118290782
commit d331015329
3 changed files with 376 additions and 1 deletions

View File

@@ -0,0 +1,256 @@
# Generated by Django 5.2.8 on 2025-12-03 11:51
import InvenTree.models
import InvenTree.validators
from django.conf import settings
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
"""Create new ParameterTemplate and Parameter models.
Ref: https://github.com/inventree/InvenTree/pull/10699
These models have been migrated from the following (existing) models:
- part.PartParameterTemplate -> common.ParameterTemplate
- part.PartParameter -> common.Parameter
To preserve the existing data, we will use the existing database tables.
For this to work, the existing models (part.PartParameterTemplate and part.PartParameter)
must have already had schema and migrations applied:
- part/migrations/0144_auto_20251203_1045.py
- part/migrations/0145_auto_20251203_1120.py
"""
dependencies = [
("common", "0039_emailthread_emailmessage"),
("part", "0145_auto_20251203_1120"),
]
operations = [
migrations.CreateModel(
name="ParameterTemplate",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"metadata",
models.JSONField(
blank=True,
help_text="JSON metadata field, for use by external plugins",
null=True,
verbose_name="Plugin Metadata",
),
),
(
"model_type",
models.ForeignKey(
blank=True, null=True,
help_text="Target model type for this parameter template",
on_delete=django.db.models.deletion.SET_NULL,
to="contenttypes.contenttype",
verbose_name="Model type",
),
),
(
"name",
models.CharField(
help_text="Parameter Name",
max_length=100,
unique=True,
verbose_name="Name",
),
),
(
"units",
models.CharField(
blank=True,
help_text="Physical units for this parameter",
max_length=25,
validators=[InvenTree.validators.validate_physical_units],
verbose_name="Units",
),
),
(
"description",
models.CharField(
blank=True,
help_text="Parameter description",
max_length=250,
verbose_name="Description",
),
),
(
"checkbox",
models.BooleanField(
default=False,
help_text="Is this parameter a checkbox?",
verbose_name="Checkbox",
),
),
(
"choices",
models.CharField(
blank=True,
help_text="Valid choices for this parameter (comma-separated)",
max_length=5000,
verbose_name="Choices",
),
),
(
"selectionlist",
models.ForeignKey(
blank=True,
help_text="Selection list for this parameter",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="templates",
to="common.selectionlist",
verbose_name="Selection List",
),
),
(
"enabled",
models.BooleanField(
default=True,
help_text="Is this parameter template enabled?",
verbose_name="Enabled",
),
)
],
options={
"verbose_name": "Parameter Template",
"verbose_name_plural": "Parameter Templates",
"db_table": "part_partparametertemplate",
"managed": False,
},
bases=(InvenTree.models.PluginValidationMixin, models.Model),
),
migrations.CreateModel(
name="Parameter",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"metadata",
models.JSONField(
blank=True,
help_text="JSON metadata field, for use by external plugins",
null=True,
verbose_name="Plugin Metadata",
),
),
(
"updated",
models.DateTimeField(
blank=True,
default=None,
help_text="Timestamp of last update",
null=True,
verbose_name="Updated",
),
),
(
"model_type",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="contenttypes.contenttype",
),
),
(
"model_id",
models.PositiveIntegerField(
help_text="ID of the target model for this parameter",
verbose_name="Model ID",
),
),
(
"data",
models.CharField(
help_text="Parameter Value",
max_length=500,
validators=[django.core.validators.MinLengthValidator(1)],
verbose_name="Data",
),
),
(
"data_numeric",
models.FloatField(blank=True, default=None, null=True),
),
(
"note",
models.CharField(
blank=True,
help_text="Optional note field",
max_length=500,
verbose_name="Note",
),
),
(
"template",
models.ForeignKey(
help_text="Parameter template",
on_delete=django.db.models.deletion.CASCADE,
related_name="parameters",
to="common.parametertemplate",
verbose_name="Template",
),
),
(
"updated_by",
models.ForeignKey(
blank=True,
help_text="User who last updated this object",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="%(class)s_updated",
to=settings.AUTH_USER_MODEL,
verbose_name="Update By",
),
),
],
options={
"verbose_name": "Parameter",
"verbose_name_plural": "Parameters",
"unique_together": {("model_type", "model_id", "template")},
"db_table": "part_partparameter",
"managed": False,
},
bases=(InvenTree.models.PluginValidationMixin, models.Model),
),
migrations.AddIndex(
model_name="parameter",
index=models.Index(
fields=["model_type", "model_id"], name="common_para_model_t_244405_idx"
),
),
migrations.AlterModelOptions(
name="parameter",
options={"verbose_name": "Parameter", "verbose_name_plural": "Parameters"},
),
migrations.AlterModelOptions(
name="parametertemplate",
options={
"verbose_name": "Parameter Template",
"verbose_name_plural": "Parameter Templates",
},
),
]

View File

@@ -61,6 +61,48 @@ def reverse_update_parameter(apps, schema_editor):
)
def update_category_parameters(apps, schema_editor):
"""Copy the 'part_template' field to the new 'template' field."""
PartCategoryParameterTemplate = apps.get_model("part", "PartCategoryParameterTemplate")
category_parameters_to_update = []
for cat_param in PartCategoryParameterTemplate.objects.all():
cat_param.template = cat_param.part_template
category_parameters_to_update.append(cat_param)
if len(category_parameters_to_update) > 0:
print(f"Updating {len(category_parameters_to_update)} PartCategoryParameterTemplate records.")
PartCategoryParameterTemplate.objects.bulk_update(
category_parameters_to_update,
fields=["template"],
)
def reverse_update_category_parameters(apps, schema_editor):
"""Copy the 'template' field back to the 'part_template' field."""
PartCategoryParameterTemplate = apps.get_model("part", "PartCategoryParameterTemplate")
category_parameters_to_update = []
for cat_param in PartCategoryParameterTemplate.objects.all():
cat_param.part_template = cat_param.template
category_parameters_to_update.append(cat_param)
if len(category_parameters_to_update) > 0:
print(f"Reversing update of {len(category_parameters_to_update)} PartCategoryParameterTemplate records.")
PartCategoryParameterTemplate.objects.bulk_update(
category_parameters_to_update,
fields=["part_template"],
)
class Migration(migrations.Migration):
"""Data migration for making the PartParameterTemplate and PartParameter models generic.
@@ -126,5 +168,49 @@ class Migration(migrations.Migration):
update_parameter,
reverse_code=reverse_update_parameter,
),
# Add a new "template" field to the PartCategoryParameterTemplate model
migrations.AddField(
model_name="partcategoryparametertemplate",
name="template",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=deletion.CASCADE,
related_name="part_categories",
to="common.parametertemplate",
),
),
# Remove unique constraint on PartCategoryParameterTemplate model
migrations.RemoveConstraint(
model_name="partcategoryparametertemplate",
name="unique_category_parameter_template_pair",
),
# Perform data migration for the PartCategoryParameterTemplate model
migrations.RunPython(
update_category_parameters,
reverse_code=reverse_update_category_parameters,
),
# Remove the obsolete "part_template" field from the PartCategoryParameterTemplate model
migrations.RemoveField(
model_name="partcategoryparametertemplate",
name="parameter_template",
),
# Remove nullable attribute from the new 'template' field
migrations.AlterField(
model_name="partcategoryparametertemplate",
name="template",
field=models.ForeignKey(
on_delete=deletion.CASCADE,
related_name="part_categories",
to="common.parametertemplate",
),
),
# Update uniqueness constraint on PartCategoryParameterTemplate model
migrations.AddConstraint(
model_name="partcategoryparametertemplate",
constraint=models.UniqueConstraint(
fields=("category", "template"),
name="unique_category_parameter_pair",
),
),
]

View File

@@ -0,0 +1,33 @@
# Generated by Django 5.2.8 on 2025-12-03 12:00
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("part", "0145_auto_20251203_1120"),
]
operations = [
migrations.RemoveField(
model_name="partparametertemplate",
name="model_type",
),
migrations.RemoveField(
model_name="partparametertemplate",
name="selectionlist",
),
migrations.DeleteModel(
name="PartParameter",
options={
"managed": False,
}
),
migrations.DeleteModel(
name="PartParameterTemplate",
options={
"managed": False,
}
),
]