Parcourir la source

Fixes #531: Order prefixes by VRF assignment

Jeremy Stretch il y a 8 ans
Parent
commit
2567412121

+ 19 - 0
netbox/ipam/migrations/0008_prefix_change_order.py

@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10 on 2016-09-15 16:08
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('ipam', '0007_prefix_ipaddress_add_tenant'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='prefix',
+            options={'ordering': ['vrf', 'family', 'prefix'], 'verbose_name_plural': 'prefixes'},
+        ),
+    ]

+ 3 - 2
netbox/ipam/models.py

@@ -12,6 +12,7 @@ from dcim.models import Interface
 from extras.models import CustomFieldModel, CustomFieldValue
 from tenancy.models import Tenant
 from utilities.models import CreatedUpdatedModel
+from utilities.sql import NullsFirstQuerySet
 
 from .fields import IPNetworkField, IPAddressField
 
@@ -192,7 +193,7 @@ class Role(models.Model):
         return self.vlans.count()
 
 
-class PrefixQuerySet(models.QuerySet):
+class PrefixQuerySet(NullsFirstQuerySet):
 
     def annotate_depth(self, limit=None):
         """
@@ -249,7 +250,7 @@ class Prefix(CreatedUpdatedModel, CustomFieldModel):
     objects = PrefixQuerySet.as_manager()
 
     class Meta:
-        ordering = ['family', 'prefix']
+        ordering = ['vrf', 'family', 'prefix']
         verbose_name_plural = 'prefixes'
 
     def __unicode__(self):

+ 32 - 0
netbox/utilities/sql.py

@@ -0,0 +1,32 @@
+from django.db import connections, models
+from django.db.models.sql.compiler import SQLCompiler
+
+
+class NullsFirstSQLCompiler(SQLCompiler):
+
+    def get_order_by(self):
+        result = super(NullsFirstSQLCompiler, self).get_order_by()
+        if result:
+            return [(expr, (sql + ' NULLS FIRST', params, is_ref)) for (expr, (sql, params, is_ref)) in result]
+        return result
+
+
+class NullsFirstQuery(models.sql.query.Query):
+
+    def get_compiler(self, using=None, connection=None):
+        if using is None and connection is None:
+            raise ValueError("Need either using or connection")
+        if using:
+            connection = connections[using]
+        return NullsFirstSQLCompiler(self, connection, using)
+
+
+class NullsFirstQuerySet(models.QuerySet):
+    """
+    Override PostgreSQL's default behavior of ordering NULLs last. This is needed e.g. to order Prefixes in the global
+    table before those assigned to a VRF.
+    """
+
+    def __init__(self, model=None, query=None, using=None, hints=None):
+        super(NullsFirstQuerySet, self).__init__(model, query, using, hints)
+        self.query = query or NullsFirstQuery(self.model)