Coverage for backend/django/Economics/shared/model_base.py: 98%
36 statements
« prev ^ index » next coverage.py v7.10.7, created at 2026-07-22 05:22 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2026-07-22 05:22 +0000
1from django.core.exceptions import ValidationError
2from django.db import models
4from core.managers import AccessControlManager
7def _validate_same_flowsheet_state(errors, field_name, value, flowsheet_state_id):
8 if value is not None and value.flowsheet_state_id != flowsheet_state_id:
9 errors[field_name] = "Referenced row must belong to the same flowsheet state."
12class FlowsheetScopedEconomicsModel(models.Model):
13 same_flowsheet_fields: tuple[str, ...] = ()
15 class Meta:
16 abstract = True
18 def clean(self):
19 super().clean()
20 errors = {}
21 for field_name in self.same_flowsheet_fields:
22 field_id_name = f"{field_name}_id"
23 if getattr(self, field_id_name, None) is None:
24 continue
25 _validate_same_flowsheet_state(
26 errors,
27 field_name,
28 getattr(self, field_name),
29 self.flowsheet_state_id,
30 )
31 if errors:
32 raise ValidationError(errors)
34 def save(self, *args, **kwargs):
35 self.full_clean()
36 return super().save(*args, **kwargs)
39class GlobalReferenceDataManager(AccessControlManager):
40 """Access-control-compatible manager for global read-only reference data.
42 Project validation expects models to use ``AccessControlManager`` or
43 ``SoftDeleteManager``. Stats NZ index rows are intentionally not
44 flowsheet-owned, so this manager preserves that contract without filtering
45 reads or pinning writes to a request flowsheet. These models are populated
46 by developer-run management commands, not ordinary user APIs.
47 """
49 def create(self, **kwargs):
50 return super(AccessControlManager, self).create(**kwargs)
52 def bulk_create(self, objs, **kwargs):
53 return super(AccessControlManager, self).bulk_create(objs, **kwargs)
55 def get_queryset(self):
56 return super(AccessControlManager, self).get_queryset()
59class GlobalReferenceDataModel(models.Model):
60 """Reference-data base that preserves model validation without flowsheet scoping."""
62 class Meta:
63 abstract = True
65 def save(self, *args, **kwargs):
66 self.full_clean()
67 return super().save(*args, **kwargs)