diff --git a/bin/smsd.py b/bin/smsd.py index 709bb8d26c..2c82a33331 100755 --- a/bin/smsd.py +++ b/bin/smsd.py @@ -29,7 +29,7 @@ import sys import time -from nav.compatibility import smart_str +from django.utils.encoding import smart_str import nav.config import nav.daemon diff --git a/python/nav/auditlog/models.py b/python/nav/auditlog/models.py index 687daf99c9..4246d6cc27 100644 --- a/python/nav/auditlog/models.py +++ b/python/nav/auditlog/models.py @@ -18,7 +18,7 @@ from __future__ import unicode_literals, absolute_import import logging -from nav.compatibility import force_str +from django.utils.encoding import force_str from django.db import models from django.utils.timezone import now as utcnow diff --git a/python/nav/auditlog/utils.py b/python/nav/auditlog/utils.py index 50fa700a65..d6f0c34c9c 100644 --- a/python/nav/auditlog/utils.py +++ b/python/nav/auditlog/utils.py @@ -16,7 +16,7 @@ # from __future__ import unicode_literals -from nav.compatibility import force_str +from django.utils.encoding import force_str from django.db.models import Q from . import find_modelname diff --git a/python/nav/compatibility.py b/python/nav/compatibility.py index e5907b0473..07ca52d024 100644 --- a/python/nav/compatibility.py +++ b/python/nav/compatibility.py @@ -1,19 +1,3 @@ -# Django 2.2 has only *_text, Django 3.2 has both *_text and *_str, -# Django 4.0 has only *_str. These are imported so many places that -# it is better to do it once, hence this file - -# When no longer supporting 2.2: -# s/nav.compatibility \(import \w+_str\)/django.utils.encoding \1/ -try: - from django.utils.encoding import force_str -except ImportError: - from django.utils.encoding import force_text as force_str - -try: - from django.utils.encoding import smart_str -except ImportError: - from django.utils.encoding import smart_text as smart_str - # lru_cache isn't used that much but one application of sed is faster # than changing a block into a line three times. diff --git a/python/nav/django/legacy.py b/python/nav/django/legacy.py index 2192355f35..08f502406c 100644 --- a/python/nav/django/legacy.py +++ b/python/nav/django/legacy.py @@ -15,10 +15,7 @@ # """Various functionality to bridge legacy NAV code with Django""" -try: - from django.utils.deprecation import MiddlewareMixin -except ImportError: # Django <= 1.9 - MiddlewareMixin = object +from django.utils.deprecation import MiddlewareMixin from nav import db diff --git a/python/nav/django/settings.py b/python/nav/django/settings.py index 5e27110c6d..1847ec24ca 100644 --- a/python/nav/django/settings.py +++ b/python/nav/django/settings.py @@ -132,8 +132,6 @@ 'nav.django.legacy.LegacyCleanupMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', ) -if django.VERSION[:2] == (1, 8): # Django <= 1.8 - MIDDLEWARE_CLASSES = MIDDLEWARE SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer' SESSION_ENGINE = 'django.contrib.sessions.backends.db' diff --git a/python/nav/django/utils.py b/python/nav/django/utils.py index 7b21113f7b..f9aaf188ad 100644 --- a/python/nav/django/utils.py +++ b/python/nav/django/utils.py @@ -60,11 +60,7 @@ def get_verbose_name(model, lookup): foreign_key, lookup = lookup.split('__', 1) try: - foreign_model_field = model._meta.get_field(foreign_key) - try: - foreign_model = foreign_model_field.remote_field.model - except AttributeError: # Django <= 1.8 - foreign_model = foreign_model_field.rel.to + foreign_model = model._meta.get_field(foreign_key).remote_field.model return get_verbose_name(foreign_model, lookup) except FieldDoesNotExist: pass diff --git a/python/nav/ipdevpoll/storage.py b/python/nav/ipdevpoll/storage.py index 7fd1fce536..5a5f38ab65 100644 --- a/python/nav/ipdevpoll/storage.py +++ b/python/nav/ipdevpoll/storage.py @@ -264,10 +264,7 @@ def get_dependencies(cls): dependencies = [] for field in cls._meta.fields: if issubclass(field.__class__, django.db.models.fields.related.ForeignKey): - try: - django_dependency = field.remote_field.model - except AttributeError: # Django <= 1.8 - django_dependency = field.rel.to + django_dependency = field.remote_field.model shadow_dependency = MetaShadow.shadowed_classes.get( django_dependency, None diff --git a/python/nav/mibs/cisco_process_mib.py b/python/nav/mibs/cisco_process_mib.py index 432dae5c6c..d2748ce561 100644 --- a/python/nav/mibs/cisco_process_mib.py +++ b/python/nav/mibs/cisco_process_mib.py @@ -16,7 +16,7 @@ # from twisted.internet import defer -from nav.compatibility import smart_str +from django.utils.encoding import smart_str from nav.smidumps import get_mib from nav.mibs import mibretriever diff --git a/python/nav/mibs/itw_mib.py b/python/nav/mibs/itw_mib.py index c7e87b2558..13cb51b715 100644 --- a/python/nav/mibs/itw_mib.py +++ b/python/nav/mibs/itw_mib.py @@ -22,7 +22,7 @@ Uses the vendor-specifica IT-WATCHDOGS-MIB to detect and collect sensor-information. """ -from nav.compatibility import smart_str +from django.utils.encoding import smart_str from twisted.internet import defer from nav.mibs import reduce_index diff --git a/python/nav/models/fields.py b/python/nav/models/fields.py index 18b29c29f0..6efc77f7b2 100644 --- a/python/nav/models/fields.py +++ b/python/nav/models/fields.py @@ -73,15 +73,9 @@ class DictAsJsonField(models.TextField): def db_type(self, connection): return 'varchar' - if django.VERSION < (2,): # Django < 2.x - # pylint: disable=unused-argument - def from_db_value(self, value, expression, connection, context): - return self.to_python(value) - - else: - # pylint: disable=unused-argument - def from_db_value(self, value, expression, connection): - return self.to_python(value) + # pylint: disable=unused-argument + def from_db_value(self, value, expression, connection): + return self.to_python(value) def to_python(self, value): if value: @@ -128,15 +122,8 @@ def __init__(self, *args, **kwargs): def db_type(self, connection): return 'point' - if django.VERSION < (2,): # Django < 2.x - - def from_db_value(self, value, expression, connection, context): - return self.to_python(value) - - else: - - def from_db_value(self, value, expression, connection): - return self.to_python(value) + def from_db_value(self, value, expression, connection): + return self.to_python(value) def to_python(self, value): if not value or isinstance(value, tuple): @@ -196,10 +183,7 @@ def contribute_to_class(self, cls, name): self.name = name self.model = cls self.cache_attr = "_%s_cache" % name - if django.VERSION[:2] == (1, 8): # Django <= 1.8 - cls._meta.virtual_fields.append(self) - else: - cls._meta.private_fields.append(self) + cls._meta.private_fields.append(self) if not cls._meta.abstract: signals.pre_init.connect(self.instance_pre_init, sender=cls) diff --git a/python/nav/web/api/v1/alert_serializers.py b/python/nav/web/api/v1/alert_serializers.py index cc6e616e89..c1e7d42ab2 100644 --- a/python/nav/web/api/v1/alert_serializers.py +++ b/python/nav/web/api/v1/alert_serializers.py @@ -18,7 +18,7 @@ from django.core.exceptions import ObjectDoesNotExist from django.template.defaultfilters import urlize from django.urls import reverse -from nav.compatibility import force_str +from django.utils.encoding import force_str from django.utils.html import strip_tags from rest_framework import serializers diff --git a/python/nav/web/api/v1/views.py b/python/nav/web/api/v1/views.py index 9cf02faba5..2e285ddc3c 100644 --- a/python/nav/web/api/v1/views.py +++ b/python/nav/web/api/v1/views.py @@ -186,10 +186,7 @@ def is_valid_field(self, model, field): # foreign key if len(components) == 2: - try: - remote_model = field.remote_field.model - except AttributeError: # Django <= 1.8 - remote_model = field.rel.to + remote_model = field.remote_field.model if remote_model: return self.is_valid_field(remote_model, components[1]) return True diff --git a/python/nav/web/auth/middleware.py b/python/nav/web/auth/middleware.py index 5d2b55daff..ed46f07bf1 100644 --- a/python/nav/web/auth/middleware.py +++ b/python/nav/web/auth/middleware.py @@ -21,11 +21,7 @@ import os from django.http import HttpResponseRedirect, HttpResponse - -try: - from django.utils.deprecation import MiddlewareMixin -except ImportError: # Django <= 1.9 - MiddlewareMixin = object +from django.utils.deprecation import MiddlewareMixin from nav.models.profiles import Account from nav.web.auth import remote_user, get_login_url, logout diff --git a/python/nav/web/useradmin/forms.py b/python/nav/web/useradmin/forms.py index 7d6546f718..80c178d634 100644 --- a/python/nav/web/useradmin/forms.py +++ b/python/nav/web/useradmin/forms.py @@ -19,7 +19,7 @@ from datetime import date, timedelta from django import forms -from nav.compatibility import force_str +from django.utils.encoding import force_str from crispy_forms.helper import FormHelper from crispy_forms_foundation.layout import ( diff --git a/requirements/django22.txt b/requirements/django22.txt deleted file mode 100644 index 5d78925e47..0000000000 --- a/requirements/django22.txt +++ /dev/null @@ -1 +0,0 @@ -Django>=2.2,<2.3 diff --git a/tests/integration/api_test.py b/tests/integration/api_test.py index 44faf5b483..f1226ced01 100644 --- a/tests/integration/api_test.py +++ b/tests/integration/api_test.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- from __future__ import print_function -from nav.compatibility import force_str +from django.utils.encoding import force_str from datetime import datetime, timedelta import json diff --git a/tests/integration/models/model_test.py b/tests/integration/models/model_test.py index 639dc2741a..e36e0a5a3f 100644 --- a/tests/integration/models/model_test.py +++ b/tests/integration/models/model_test.py @@ -8,15 +8,11 @@ from django.db import connection -try: - # Django >= 1.8 - import django.apps - - get_models = django.apps.apps.get_models - del django.apps -except ImportError: - # Django < 1.9 - from django.db.models import get_models +import django.apps + +get_models = django.apps.apps.get_models +del django.apps + import pytest diff --git a/tests/integration/seeddb_test.py b/tests/integration/seeddb_test.py index 0a11c10811..bfd6b6bb97 100644 --- a/tests/integration/seeddb_test.py +++ b/tests/integration/seeddb_test.py @@ -5,7 +5,7 @@ from django.test.client import RequestFactory from mock import MagicMock -from nav.compatibility import smart_str +from django.utils.encoding import smart_str from nav.models.manage import Netbox, Room from nav.web.seeddb.page.netbox.edit import netbox_edit, log_netbox_change from nav.web.seeddb.utils.delete import dependencies diff --git a/tests/integration/web/alertprofiles_test.py b/tests/integration/web/alertprofiles_test.py index cc9d72850c..9ef91afcf3 100644 --- a/tests/integration/web/alertprofiles_test.py +++ b/tests/integration/web/alertprofiles_test.py @@ -7,7 +7,7 @@ from django.test.client import RequestFactory from django.urls import reverse -from nav.compatibility import smart_str +from django.utils.encoding import smart_str from nav.models.profiles import ( AlertAddress, AlertPreference, diff --git a/tests/integration/web/devicehistory_test.py b/tests/integration/web/devicehistory_test.py index 9c13932030..748661fc36 100644 --- a/tests/integration/web/devicehistory_test.py +++ b/tests/integration/web/devicehistory_test.py @@ -4,7 +4,7 @@ from nav.models.event import EventQueue, EventQueueVar from django.urls import reverse -from nav.compatibility import smart_str +from django.utils.encoding import smart_str def test_post_device_error_should_succeed(client, localhost): diff --git a/tests/integration/web/ipdevinfo_test.py b/tests/integration/web/ipdevinfo_test.py index a3c6b86570..b04d25129c 100644 --- a/tests/integration/web/ipdevinfo_test.py +++ b/tests/integration/web/ipdevinfo_test.py @@ -2,7 +2,7 @@ from __future__ import print_function from django.urls import reverse -from nav.compatibility import smart_str +from django.utils.encoding import smart_str from nav.models.manage import Netbox, Module, Interface, Device, NetboxProfile from nav.web.ipdevinfo.utils import get_module_view diff --git a/tests/integration/web/maintenance/views_test.py b/tests/integration/web/maintenance/views_test.py index 1987c62c2d..608fbe7e8e 100644 --- a/tests/integration/web/maintenance/views_test.py +++ b/tests/integration/web/maintenance/views_test.py @@ -18,7 +18,7 @@ import pytest from django.urls import reverse -from nav.compatibility import smart_str +from django.utils.encoding import smart_str from nav.models.manage import Netbox from nav.models.msgmaint import MaintenanceTask diff --git a/tests/integration/web/netboxtype_test.py b/tests/integration/web/netboxtype_test.py index 8375fc4f7d..616dd4cf65 100644 --- a/tests/integration/web/netboxtype_test.py +++ b/tests/integration/web/netboxtype_test.py @@ -5,7 +5,7 @@ from nav.web.seeddb.forms import SEPARATOR from django.urls import reverse -from nav.compatibility import smart_str +from django.utils.encoding import smart_str def test_post_netboxtype_with_sysobjectid_without_leading_period_should_succeed(client): diff --git a/tests/integration/web/prefixviewset_test.py b/tests/integration/web/prefixviewset_test.py index 2be61de0f5..ddc93241b0 100644 --- a/tests/integration/web/prefixviewset_test.py +++ b/tests/integration/web/prefixviewset_test.py @@ -2,7 +2,7 @@ import pytest from nav.models.manage import Prefix, Vlan, NetType -from nav.compatibility import force_str +from django.utils.encoding import force_str from nav.web.api.v1.views import get_endpoints ENDPOINTS = {name: force_str(url) for name, url in get_endpoints().items()} diff --git a/tests/integration/web/webfront_test.py b/tests/integration/web/webfront_test.py index d64684af73..fec53f095f 100644 --- a/tests/integration/web/webfront_test.py +++ b/tests/integration/web/webfront_test.py @@ -1,7 +1,7 @@ from mock import Mock from django.urls import reverse -from nav.compatibility import smart_str +from django.utils.encoding import smart_str from nav.models.profiles import AccountDashboard from nav.web.webfront.utils import tool_list