Arthur пре 1 дан
родитељ
комит
8632ec3be1

+ 2 - 2
netbox/circuits/migrations/0061_generated_fields.py

@@ -7,7 +7,7 @@ import django.db.models.expressions
 import django.db.models.functions.comparison
 from django.db import migrations, models
 
-import utilities.conversion
+import utilities.fields
 
 
 # PostgreSQL cannot convert an existing column to a generated column in place, so each normalized
@@ -26,7 +26,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name="circuit",
             name="_abs_distance",
-            field=utilities.conversion.NonNegativeGeneratedField(
+            field=utilities.fields.NonNegativeGeneratedField(
                 db_persist=True,
                 expression=models.Case(
                     models.When(

+ 15 - 15
netbox/dcim/migrations/0252_generated_fields.py

@@ -8,7 +8,7 @@ import django.db.models.functions.comparison
 import django.db.models.functions.math
 from django.db import migrations, models
 
-import utilities.conversion
+import utilities.fields
 
 
 # PostgreSQL cannot convert an existing column to a generated column in place, so each normalized
@@ -27,7 +27,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name="cable",
             name="_abs_length",
-            field=utilities.conversion.NonNegativeGeneratedField(
+            field=utilities.fields.NonNegativeGeneratedField(
                 db_persist=True,
                 expression=models.Case(
                     models.When(
@@ -104,7 +104,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name="coolingfeed",
             name="_abs_max_flow",
-            field=utilities.conversion.NonNegativeGeneratedField(
+            field=utilities.fields.NonNegativeGeneratedField(
                 db_persist=True,
                 expression=models.Case(
                     models.When(
@@ -151,7 +151,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name="coolingintake",
             name="_abs_diameter",
-            field=utilities.conversion.NonNegativeGeneratedField(
+            field=utilities.fields.NonNegativeGeneratedField(
                 db_persist=True,
                 expression=models.Case(
                     models.When(
@@ -198,7 +198,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name="coolingintake",
             name="_abs_max_flow",
-            field=utilities.conversion.NonNegativeGeneratedField(
+            field=utilities.fields.NonNegativeGeneratedField(
                 db_persist=True,
                 expression=models.Case(
                     models.When(
@@ -245,7 +245,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name="coolingintaketemplate",
             name="_abs_diameter",
-            field=utilities.conversion.NonNegativeGeneratedField(
+            field=utilities.fields.NonNegativeGeneratedField(
                 db_persist=True,
                 expression=models.Case(
                     models.When(
@@ -292,7 +292,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name="coolingintaketemplate",
             name="_abs_max_flow",
-            field=utilities.conversion.NonNegativeGeneratedField(
+            field=utilities.fields.NonNegativeGeneratedField(
                 db_persist=True,
                 expression=models.Case(
                     models.When(
@@ -339,7 +339,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name="coolingoutflow",
             name="_abs_diameter",
-            field=utilities.conversion.NonNegativeGeneratedField(
+            field=utilities.fields.NonNegativeGeneratedField(
                 db_persist=True,
                 expression=models.Case(
                     models.When(
@@ -386,7 +386,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name="coolingoutflowtemplate",
             name="_abs_diameter",
-            field=utilities.conversion.NonNegativeGeneratedField(
+            field=utilities.fields.NonNegativeGeneratedField(
                 db_persist=True,
                 expression=models.Case(
                     models.When(
@@ -433,7 +433,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name="devicetype",
             name="_abs_weight",
-            field=utilities.conversion.NonNegativeGeneratedField(
+            field=utilities.fields.NonNegativeGeneratedField(
                 db_persist=True,
                 expression=django.db.models.functions.comparison.Cast(
                     django.db.models.functions.math.Floor(
@@ -497,7 +497,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name="moduletype",
             name="_abs_weight",
-            field=utilities.conversion.NonNegativeGeneratedField(
+            field=utilities.fields.NonNegativeGeneratedField(
                 db_persist=True,
                 expression=django.db.models.functions.comparison.Cast(
                     django.db.models.functions.math.Floor(
@@ -561,7 +561,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name="rack",
             name="_abs_max_weight",
-            field=utilities.conversion.NonNegativeGeneratedField(
+            field=utilities.fields.NonNegativeGeneratedField(
                 db_persist=True,
                 expression=django.db.models.functions.comparison.Cast(
                     django.db.models.functions.math.Floor(
@@ -625,7 +625,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name="rack",
             name="_abs_weight",
-            field=utilities.conversion.NonNegativeGeneratedField(
+            field=utilities.fields.NonNegativeGeneratedField(
                 db_persist=True,
                 expression=django.db.models.functions.comparison.Cast(
                     django.db.models.functions.math.Floor(
@@ -689,7 +689,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name="racktype",
             name="_abs_max_weight",
-            field=utilities.conversion.NonNegativeGeneratedField(
+            field=utilities.fields.NonNegativeGeneratedField(
                 db_persist=True,
                 expression=django.db.models.functions.comparison.Cast(
                     django.db.models.functions.math.Floor(
@@ -753,7 +753,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name="racktype",
             name="_abs_weight",
-            field=utilities.conversion.NonNegativeGeneratedField(
+            field=utilities.fields.NonNegativeGeneratedField(
                 db_persist=True,
                 expression=django.db.models.functions.comparison.Cast(
                     django.db.models.functions.math.Floor(

+ 2 - 2
netbox/dcim/models/cables.py

@@ -22,10 +22,10 @@ from dcim.fields import PathField
 from dcim.utils import decompile_path_node, object_to_path_node, rebuild_cable_paths
 from netbox.choices import ColorChoices
 from netbox.models import ChangeLoggedModel, PrimaryModel
-from utilities.conversion import LENGTH_TO_METERS, NonNegativeGeneratedField, normalized_unit_expression
+from utilities.conversion import LENGTH_TO_METERS, normalized_unit_expression
 from utilities.data import normalize_update_fields
 from utilities.exceptions import AbortRequest
-from utilities.fields import ColorField, GenericArrayForeignKey
+from utilities.fields import ColorField, GenericArrayForeignKey, NonNegativeGeneratedField
 from utilities.querysets import RestrictedQuerySet, chunked_update
 from utilities.serialization import deserialize_object, serialize_object
 from wireless.models import WirelessLink

+ 1 - 1
netbox/dcim/models/mixins.py

@@ -13,10 +13,10 @@ from netbox.choices import *
 from utilities.conversion import (
     DIAMETER_TO_MILLIMETERS,
     FLOW_RATE_TO_LITERS_PER_MINUTE,
-    NonNegativeGeneratedField,
     normalized_unit_expression,
 )
 from utilities.data import normalize_update_fields
+from utilities.fields import NonNegativeGeneratedField
 
 __all__ = (
     'CachedScopeMixin',

+ 2 - 2
netbox/dcim/models/racks.py

@@ -17,9 +17,9 @@ from netbox.choices import ColorChoices
 from netbox.models import OrganizationalModel, PrimaryModel
 from netbox.models.features import ContactsMixin, ImageAttachmentsMixin
 from netbox.models.mixins import WeightMixin
-from utilities.conversion import WEIGHT_TO_GRAMS, NonNegativeGeneratedField, normalized_unit_expression
+from utilities.conversion import WEIGHT_TO_GRAMS, normalized_unit_expression
 from utilities.data import array_to_string, drange
-from utilities.fields import ColorField, CounterCacheField
+from utilities.fields import ColorField, CounterCacheField, NonNegativeGeneratedField
 from utilities.tracking import TrackingModelMixin
 
 from .device_components import PowerPort

+ 2 - 6
netbox/netbox/models/mixins.py

@@ -4,12 +4,8 @@ from django.db import models
 from django.utils.translation import gettext_lazy as _
 
 from netbox.choices import *
-from utilities.conversion import (
-    LENGTH_TO_METERS,
-    WEIGHT_TO_GRAMS,
-    NonNegativeGeneratedField,
-    normalized_unit_expression,
-)
+from utilities.conversion import LENGTH_TO_METERS, WEIGHT_TO_GRAMS, normalized_unit_expression
+from utilities.fields import NonNegativeGeneratedField
 
 __all__ = (
     'DistanceMixin',

+ 1 - 14
netbox/utilities/conversion.py

@@ -1,6 +1,6 @@
 from decimal import ROUND_HALF_UP, Decimal, InvalidOperation
 
-from django.db.models import BigIntegerField, Case, DecimalField, F, GeneratedField, Value, When
+from django.db.models import BigIntegerField, Case, DecimalField, F, Value, When
 from django.db.models.functions import Cast, Floor
 from django.utils.translation import gettext as _
 
@@ -16,7 +16,6 @@ __all__ = (
     'FLOW_RATE_TO_LITERS_PER_MINUTE',
     'LENGTH_TO_METERS',
     'WEIGHT_TO_GRAMS',
-    'NonNegativeGeneratedField',
     'normalized_unit_expression',
     'to_grams',
     'to_liters_per_minute',
@@ -66,18 +65,6 @@ FLOW_RATE_TO_LITERS_PER_MINUTE = {
 # Database expressions
 #
 
-class NonNegativeGeneratedField(GeneratedField):
-    """
-    A generated column which the database constrains to non-negative values via an inline CHECK, as it would a
-    PositiveIntegerField. Django emits no check for a GeneratedField's output_field because that field is never
-    bound to a column, so the check is supplied here from the generated column itself.
-    """
-    def db_parameters(self, connection):
-        params = super().db_parameters(connection)
-        params['check'] = f'{connection.ops.quote_name(self.column)} >= 0'
-        return params
-
-
 def normalized_unit_expression(value_field, unit_field, factors, integer=False):
     """
     Return a database expression converting `value_field` to its base unit according to the value of `unit_field`,

+ 15 - 1
netbox/utilities/fields.py

@@ -8,7 +8,6 @@ from django.db.models.fields.mixins import FieldCacheMixin
 from django.utils.functional import cached_property
 from django.utils.translation import gettext_lazy as _
 
-from .forms.widgets import ColorSelect
 from .validators import ColorValidator
 
 __all__ = (
@@ -16,6 +15,7 @@ __all__ = (
     'CounterCacheField',
     'GenericArrayForeignKey',
     'NaturalOrderingField',
+    'NonNegativeGeneratedField',
     'RestrictedGenericForeignKey',
 )
 
@@ -29,10 +29,24 @@ class ColorField(models.CharField):
         super().__init__(*args, **kwargs)
 
     def formfield(self, **kwargs):
+        # Imported here because utilities.forms indirectly imports netbox.models, which imports this module
+        from .forms.widgets import ColorSelect
         kwargs['widget'] = ColorSelect
         return super().formfield(**kwargs)
 
 
+class NonNegativeGeneratedField(models.GeneratedField):
+    """
+    A generated column which the database constrains to non-negative values via an inline CHECK, as it would a
+    PositiveIntegerField. Django emits no check for a GeneratedField's output_field because that field is never
+    bound to a column, so the check is supplied here from the generated column itself.
+    """
+    def db_parameters(self, connection):
+        params = super().db_parameters(connection)
+        params['check'] = f'{connection.ops.quote_name(self.column)} >= 0'
+        return params
+
+
 class NaturalOrderingField(models.CharField):
     """
     A field which stores a naturalized representation of its target field, to be used for ordering its parent model.

+ 2 - 2
netbox/wireless/migrations/0025_generated_fields.py

@@ -7,7 +7,7 @@ import django.db.models.expressions
 import django.db.models.functions.comparison
 from django.db import migrations, models
 
-import utilities.conversion
+import utilities.fields
 
 
 # PostgreSQL cannot convert an existing column to a generated column in place, so each normalized
@@ -26,7 +26,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name="wirelesslink",
             name="_abs_distance",
-            field=utilities.conversion.NonNegativeGeneratedField(
+            field=utilities.fields.NonNegativeGeneratedField(
                 db_persist=True,
                 expression=models.Case(
                     models.When(