From cd8de0847c4c9f717d629de14829f3c713b25e10 Mon Sep 17 00:00:00 2001 From: Jonas Braathen Date: Tue, 3 Nov 2026 03:52:20 +0100 Subject: [PATCH] chore: upgrade to django 5.2 lts --- dpdapi/admin.py | 6 +- dpdapi/models.py | 21 +++--- dpdapisite/settings.py | 147 ++++++++++++++++++----------------------- dpdapisite/urls.py | 14 ++-- dpdapisite/wsgi.py | 10 +-- 5 files changed, 83 insertions(+), 115 deletions(-) diff --git a/dpdapi/admin.py b/dpdapi/admin.py index fe98ee3..832ffed 100644 --- a/dpdapi/admin.py +++ b/dpdapi/admin.py @@ -5,9 +5,9 @@ from dpdapi.models import Alias, Domain, User @admin.register(Alias) class AliasAdmin(admin.ModelAdmin): - list_display = ['source', 'destination', 'active', 'domain'] - list_filter = ['domain'] - search_fields = ['source', 'destination'] + list_display = ("source", "destination", "active", "domain") + list_filter = ("domain",) + search_fields = ("source", "destination") @admin.register(Domain) diff --git a/dpdapi/models.py b/dpdapi/models.py index aa8d721..507b056 100644 --- a/dpdapi/models.py +++ b/dpdapi/models.py @@ -12,21 +12,21 @@ class BaseModel(models.Model): class Alias(BaseModel): source = models.EmailField(max_length=254) destination = models.EmailField(max_length=254) - domain = models.ForeignKey('dpdapi.Domain', models.CASCADE) + domain = models.ForeignKey("dpdapi.Domain", models.CASCADE) active = models.BooleanField(default=True) + class Meta: + verbose_name_plural = "aliases" + unique_together = ("source", "destination", "domain") + def __str__(self): - return "{}={}".format(self.source, self.destination) + return f"{self.source}={self.destination}" def save(self, *args, **kwargs): self.source = self.source.lower() self.destination = self.destination.lower() - super(Alias, self).save(*args, **kwargs) - - class Meta: - verbose_name_plural = 'aliases' - unique_together = ('source', 'destination', 'domain') + super().save(*args, **kwargs) class Domain(BaseModel): @@ -38,13 +38,13 @@ class Domain(BaseModel): def save(self, *args, **kwargs): self.name = self.name.lower() - super(Domain, self).save(*args, **kwargs) + super().save(*args, **kwargs) class User(BaseModel): email = models.EmailField(max_length=254, unique=True) password = models.CharField(max_length=512) - domain = models.ForeignKey('dpdapi.Domain', models.CASCADE) + domain = models.ForeignKey("dpdapi.Domain", models.CASCADE) def __str__(self): return self.email @@ -52,5 +52,4 @@ class User(BaseModel): def save(self, *args, **kwargs): self.email = self.email.lower() - super(User, self).save(*args, **kwargs) - + super().save(*args, **kwargs) diff --git a/dpdapisite/settings.py b/dpdapisite/settings.py index ec3146d..3149247 100644 --- a/dpdapisite/settings.py +++ b/dpdapisite/settings.py @@ -1,25 +1,26 @@ """ For more information on this file, see -https://docs.djangoproject.com/en/1.7/topics/settings/ +https://docs.djangoproject.com/en/stable/topics/settings/ For the full list of settings and their values, see -https://docs.djangoproject.com/en/1.7/ref/settings/ +https://docs.djangoproject.com/en/stable/ref/settings/ """ -# Build paths inside the project like this: os.path.join(BASE_DIR, ...) import os +from contextlib import suppress +from pathlib import Path import sentry_sdk from sentry_sdk.integrations.django import DjangoIntegration -BASE_DIR = os.path.dirname(os.path.dirname(__file__)) +BASE_DIR = Path(__file__).resolve().parent.parent # Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ +# See https://docs.djangoproject.com/en/stable/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'hlaf#yma(8s!cy-bf5e6kc&_5n_l1h!34c(j32-b3v8o7pg$5n' +SECRET_KEY = "django-insecure-hlaf#yma(8s!cy-bf5e6kc&_5n_l1h!34c(j32-b3v8o7pg$5n" # noqa: S105 # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -28,123 +29,103 @@ ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.messages', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.staticfiles', - - 'django_extensions', - 'rest_framework', - 'django_filters', + "django.contrib.admin", + "django.contrib.messages", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.staticfiles", + "django_extensions", + "ninja", ] INSTALLED_APPS += [ - 'dpdapi', + "dpdapi", ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", ] -ROOT_URLCONF = 'dpdapisite.urls' +ROOT_URLCONF = "dpdapisite.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [ + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [ # insert your TEMPLATE_DIRS here ], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", ], }, }, ] -WSGI_APPLICATION = 'dpdapisite.wsgi.application' +WSGI_APPLICATION = "dpdapisite.wsgi.application" # Database -# https://docs.djangoproject.com/en/1.7/ref/settings/#databases +# https://docs.djangoproject.com/en/stable/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": BASE_DIR / "db.sqlite3", } } # Internationalization -# https://docs.djangoproject.com/en/1.7/topics/i18n/ -LANGUAGE_CODE = 'en-us' -TIME_ZONE = 'Europe/Oslo' +# https://docs.djangoproject.com/en/stable/topics/i18n/ +LANGUAGE_CODE = "en-us" +TIME_ZONE = "Europe/Oslo" USE_I18N = True -USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/1.7/howto/static-files/ -STATIC_URL = '/static/' +# https://docs.djangoproject.com/en/stable/howto/static-files/ +STATIC_URL = "/static/" + +# Postfix and Dovecot read these tables directly; keep the existing integer id columns. +DEFAULT_AUTO_FIELD = "django.db.models.AutoField" -REST_FRAMEWORK = { - 'DEFAULT_AUTHENTICATION_CLASSES': ( - 'rest_framework.authentication.BasicAuthentication', - 'rest_framework.authentication.SessionAuthentication', - ) -} LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, - 'root': { - 'level': 'INFO', - 'handlers': ['console'], + "version": 1, + "disable_existing_loggers": False, + "root": { + "level": "INFO", + "handlers": ["console"], }, - 'formatters': { - 'verbose': { - 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s' - }, + "formatters": { + "verbose": {"format": "%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s"}, }, - 'handlers': { - 'console': { - 'level': 'DEBUG', - 'class': 'logging.StreamHandler', - 'formatter': 'verbose' - } - }, - 'loggers': { - 'django.db.backends': { - 'level': 'ERROR', - 'handlers': ['console'], - 'propagate': False, + "handlers": {"console": {"level": "DEBUG", "class": "logging.StreamHandler", "formatter": "verbose"}}, + "loggers": { + "django.db.backends": { + "level": "ERROR", + "handlers": ["console"], + "propagate": False, }, }, } -SENTRY_DSN = os.getenv('SENTRY_DSN', 'https://c7e6a47844484c0a81a98e10e48c1b71@sentry.neuf.no/8') +SENTRY_DSN = os.getenv("SENTRY_DSN", "https://c7e6a47844484c0a81a98e10e48c1b71@sentry.neuf.no/8") if SENTRY_DSN: - SENTRY_ENVIRONMENT = os.getenv('SENTRY_ENVIRONMENT', 'production') - sentry_sdk.init( - dsn=SENTRY_DSN, - environment=SENTRY_ENVIRONMENT, - integrations=[DjangoIntegration()] - ) + SENTRY_ENVIRONMENT = os.getenv("SENTRY_ENVIRONMENT", "production") + sentry_sdk.init(dsn=SENTRY_DSN, environment=SENTRY_ENVIRONMENT, integrations=[DjangoIntegration()]) -try: - from .local_settings import * -except ImportError: - pass +with suppress(ImportError): + from .local_settings import * # noqa: F403 diff --git a/dpdapisite/urls.py b/dpdapisite/urls.py index f8e8e65..463ac72 100644 --- a/dpdapisite/urls.py +++ b/dpdapisite/urls.py @@ -1,14 +1,10 @@ -from django.conf.urls import include, url from django.contrib import admin +from django.urls import include, path from django.views.generic import RedirectView -from rest_framework import urls as rest_framework_urls -from dpdapi import urls as dpdapi_urls - - urlpatterns = [ - url(r'^$', RedirectView.as_view(pattern_name='api-root')), - url(r'^api/', include(dpdapi_urls)), - url(r'^admin/', admin.site.urls), - url(r'^api-auth/', include(rest_framework_urls, namespace='rest_framework')) + path("", RedirectView.as_view(pattern_name="api-root")), + path("api/", include("dpdapi.urls")), + path("admin/", admin.site.urls), + path("api-auth/", include("rest_framework.urls", namespace="rest_framework")), ] diff --git a/dpdapisite/wsgi.py b/dpdapisite/wsgi.py index 002f71e..528aee7 100644 --- a/dpdapisite/wsgi.py +++ b/dpdapisite/wsgi.py @@ -1,13 +1,5 @@ -""" -WSGI config for pfrsite project. - -It exposes the WSGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/ -""" - import os + from django.core.wsgi import get_wsgi_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dpdapisite.settings")