From 2a0744f6020688373273788c6c6be27c15f29967 Mon Sep 17 00:00:00 2001 From: Nikolai Kristiansen Date: Wed, 6 Jan 2016 22:39:32 +0100 Subject: [PATCH 1/2] Override form in InterfaceInline to get to expensive lookup --- mdb/admin.py | 3 ++- mdb/forms.py | 22 ++++++++++++++++++++++ mdb/models.py | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 mdb/forms.py diff --git a/mdb/admin.py b/mdb/admin.py index 3c7694c..3fc9f44 100644 --- a/mdb/admin.py +++ b/mdb/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin, messages - +from mdb.forms import InterfaceForm from mdb.models import Ip6Address, Interface, Ip4Address, DhcpOption, DhcpCustomField, DomainSrvRecord, DomainTxtRecord, \ DomainCnameRecord, DomainARecord, Domain, Host, Ip4Subnet, Ip6Subnet, Nameserver, MailExchange, OperatingSystem, \ HostType, DhcpConfig, DomainAAAARecord @@ -14,6 +14,7 @@ class InterfaceInline(admin.TabularInline): inlines = [Ip6AddressInline] model = Interface extra = 0 + form = InterfaceForm def get_queryset(self, request): return super(InterfaceInline, self).get_queryset(request).select_related() diff --git a/mdb/forms.py b/mdb/forms.py new file mode 100644 index 0000000..51dfd6f --- /dev/null +++ b/mdb/forms.py @@ -0,0 +1,22 @@ +from django import forms +from django.forms import ModelChoiceField + +from mdb.models import Interface, Ip4Address + + +class Ipv4ModelChoiceField(ModelChoiceField): + # def __init__(self, *args, **kwargs): + # super(Ipv4ModelChoiceField, self).__init__(*args, **kwargs) + + def label_from_instance(self, obj): + # TODO improve those labelZ + return obj.__str__() + + +class InterfaceForm(forms.ModelForm): + model = Interface + + def __init__(self, *args, **kwargs): + super(InterfaceForm, self).__init__(*args, **kwargs) + + self.fields['ip4address'] = Ipv4ModelChoiceField(queryset=Ip4Address.objects.select_related()) diff --git a/mdb/models.py b/mdb/models.py index eb3f3f1..f83aee9 100644 --- a/mdb/models.py +++ b/mdb/models.py @@ -476,6 +476,7 @@ class Ip4Address(models.Model): if not hasattr(self, 'interface'): return self.address + # FIXME: Remove this when admin is overridden return "{} ({})".format(self.address, self.interface.host.hostname) def assigned_to_host(self): From 898578852d684ef9b625a2a0857201e5758fee68 Mon Sep 17 00:00:00 2001 From: Nikolai R Kristiansen Date: Thu, 7 Jan 2016 23:39:11 +0100 Subject: [PATCH 2/2] select_related to the rescue, such performance! --- mdb/forms.py | 16 +++++++++------- mdb/models.py | 7 +------ mdbsite/settings.py | 1 + mdbsite/wsgi.py | 7 ++++--- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/mdb/forms.py b/mdb/forms.py index 51dfd6f..2a0d4d0 100644 --- a/mdb/forms.py +++ b/mdb/forms.py @@ -4,13 +4,12 @@ from django.forms import ModelChoiceField from mdb.models import Interface, Ip4Address -class Ipv4ModelChoiceField(ModelChoiceField): - # def __init__(self, *args, **kwargs): - # super(Ipv4ModelChoiceField, self).__init__(*args, **kwargs) - +class Ip4ModelChoiceField(ModelChoiceField): def label_from_instance(self, obj): - # TODO improve those labelZ - return obj.__str__() + if not hasattr(obj, 'interface'): + return obj.address + + return "{} ({})".format(obj.address, obj.interface.host.hostname) class InterfaceForm(forms.ModelForm): @@ -19,4 +18,7 @@ class InterfaceForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(InterfaceForm, self).__init__(*args, **kwargs) - self.fields['ip4address'] = Ipv4ModelChoiceField(queryset=Ip4Address.objects.select_related()) + # Join Ip4Address with tables interface and host, + # before printing the select labels that walk those two relations. + queryset = Ip4Address.objects.select_related('interface', 'interface__host') + self.fields['ip4address'] = Ip4ModelChoiceField(queryset=queryset) diff --git a/mdb/models.py b/mdb/models.py index f83aee9..5e55122 100644 --- a/mdb/models.py +++ b/mdb/models.py @@ -472,12 +472,7 @@ class Ip4Address(models.Model): ping_avg_rtt = models.FloatField(null=True, blank=True) def __str__(self): - # FIXME: generates 2 SQL queries? - if not hasattr(self, 'interface'): - return self.address - - # FIXME: Remove this when admin is overridden - return "{} ({})".format(self.address, self.interface.host.hostname) + return self.address def assigned_to_host(self): return self.interface.host diff --git a/mdbsite/settings.py b/mdbsite/settings.py index 1e0549c..bf04d3a 100644 --- a/mdbsite/settings.py +++ b/mdbsite/settings.py @@ -76,6 +76,7 @@ INSTALLED_APPS = ( 'django.contrib.admin', 'rest_framework', 'rest_framework.authtoken', + 'django_extensions', 'mdb', ) diff --git a/mdbsite/wsgi.py b/mdbsite/wsgi.py index cbb5e87..ac62e0d 100644 --- a/mdbsite/wsgi.py +++ b/mdbsite/wsgi.py @@ -1,5 +1,6 @@ -import os -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mdb.settings") - from django.core.wsgi import get_wsgi_application +import os + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mdbsite.settings") + application = get_wsgi_application()