From 2d3e8b2a5641cadb336fb047e3545dc0d2996afc Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Sun, 9 Mar 2025 15:04:46 +0100 Subject: [PATCH 1/2] Update to Django 5.2b1 --- pyproject.toml | 2 +- src/servala/asgi.py | 16 ---------------- src/servala/settings.py | 5 ++--- src/servala/urls.py | 2 +- src/servala/wsgi.py | 2 +- uv.lock | 8 ++++---- 6 files changed, 9 insertions(+), 26 deletions(-) delete mode 100644 src/servala/asgi.py diff --git a/pyproject.toml b/pyproject.toml index 8c7c08e..3639b23 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ readme = "README.md" requires-python = ">=3.12" dependencies = [ "argon2-cffi>=23.1.0", - "django==4.2", + "django==5.2b1", "psycopg2-binary>=2.9.10", ] diff --git a/src/servala/asgi.py b/src/servala/asgi.py deleted file mode 100644 index 5118350..0000000 --- a/src/servala/asgi.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -ASGI config for servala project. - -It exposes the ASGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/ -""" - -import os - -from django.core.asgi import get_asgi_application - -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "servala.settings") - -application = get_asgi_application() diff --git a/src/servala/settings.py b/src/servala/settings.py index ab8e128..f4a84f9 100644 --- a/src/servala/settings.py +++ b/src/servala/settings.py @@ -5,8 +5,8 @@ Servala is run using environment variables. Documentation: - README.md for project information - .env.example for environment variables in use -- Django settings guide: https://docs.djangoproject.com/en/4.2/topics/settings/ -- Django settings reference: https://docs.djangoproject.com/en/4.2/ref/settings/ +- Django settings guide: https://docs.djangoproject.com/en/5.2/topics/settings/ +- Django settings reference: https://docs.djangoproject.com/en/5.2/ref/settings/ """ import os @@ -99,7 +99,6 @@ TEMPLATES = [ "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", diff --git a/src/servala/urls.py b/src/servala/urls.py index 78d0d41..216891d 100644 --- a/src/servala/urls.py +++ b/src/servala/urls.py @@ -2,7 +2,7 @@ URL configuration for servala project. The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/4.2/topics/http/urls/ + https://docs.djangoproject.com/en/5.2/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views diff --git a/src/servala/wsgi.py b/src/servala/wsgi.py index 8ebdcca..0e17483 100644 --- a/src/servala/wsgi.py +++ b/src/servala/wsgi.py @@ -4,7 +4,7 @@ WSGI config for servala 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/4.2/howto/deployment/wsgi/ +https://docs.djangoproject.com/en/5.2/howto/deployment/wsgi/ """ import os diff --git a/uv.lock b/uv.lock index 8adedc4..69c4b3c 100644 --- a/uv.lock +++ b/uv.lock @@ -147,16 +147,16 @@ wheels = [ [[package]] name = "django" -version = "4.2" +version = "5.2b1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "asgiref" }, { name = "sqlparse" }, { name = "tzdata", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9a/bb/48aa3e0850923096dff2766d21a6004d6e1a3317f0bd400ba81f586754e1/Django-4.2.tar.gz", hash = "sha256:c36e2ab12824e2ac36afa8b2515a70c53c7742f0d6eaefa7311ec379558db997", size = 10415665 } +sdist = { url = "https://files.pythonhosted.org/packages/f6/22/ae506393d2fb47d8ea8256cb600072b02d971134e26bd1d4b8fbfb8fca9e/Django-5.2b1.tar.gz", hash = "sha256:55c764c5990759ee97ba60ac1ce17092e91e445be1d0a83e88b754835c4bb564", size = 10816962 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/40/6012f98b14b64b4d3dc47b0c2f116fccbd0795ab35515d0c40dac73b81b8/Django-4.2-py3-none-any.whl", hash = "sha256:ad33ed68db9398f5dfb33282704925bce044bef4261cd4fb59e4e7f9ae505a78", size = 7988617 }, + { url = "https://files.pythonhosted.org/packages/00/6a/4e53c567ef24e81e17a30c788209396e08b8aaf8011d9cf01b8aa4910fa1/Django-5.2b1-py3-none-any.whl", hash = "sha256:ec33b0b3846d145a95d84a1ffea29f64ce4fc73ba755d9a6ab35128f354b750a", size = 8295550 }, ] [[package]] @@ -502,7 +502,7 @@ dev = [ [package.metadata] requires-dist = [ { name = "argon2-cffi", specifier = ">=23.1.0" }, - { name = "django", specifier = "==4.2" }, + { name = "django", specifier = "==5.2b1" }, { name = "psycopg2-binary", specifier = ">=2.9.10" }, ] From 6702de359bcff016cb2f9497f80776d6af01e01a Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Sun, 9 Mar 2025 15:21:12 +0100 Subject: [PATCH 2/2] Add custom user model --- src/servala/core/models/__init__.py | 2 ++ src/servala/core/models/user.py | 38 +++++++++++++++++++++++++++++ src/servala/settings.py | 1 + 3 files changed, 41 insertions(+) create mode 100644 src/servala/core/models/user.py diff --git a/src/servala/core/models/__init__.py b/src/servala/core/models/__init__.py index 28a75be..110d9d7 100644 --- a/src/servala/core/models/__init__.py +++ b/src/servala/core/models/__init__.py @@ -14,6 +14,7 @@ from .service import ( ServiceOfferingPlan, ServiceProvider, ) +from .user import User __all__ = [ "BillingEntity", @@ -28,4 +29,5 @@ __all__ = [ "ServiceOffering", "ServiceOfferingPlan", "ServiceProvider", + "User", ] diff --git a/src/servala/core/models/user.py b/src/servala/core/models/user.py new file mode 100644 index 0000000..a514420 --- /dev/null +++ b/src/servala/core/models/user.py @@ -0,0 +1,38 @@ +from django.contrib.auth.models import AbstractBaseUser +from django.db import models +from django.utils.translation import gettext_lazy as _ + + +class User(AbstractBaseUser): + """The Django model provides a password and last_login field.""" + + email = models.EmailField(unique=True, verbose_name=_("Email address")) + first_name = models.CharField( + max_length=30, blank=True, verbose_name=_("First name") + ) + last_name = models.CharField(max_length=30, blank=True, verbose_name=_("Last name")) + company = models.CharField(max_length=100, blank=True, verbose_name=_("Company")) + + is_staff = models.BooleanField( + default=False, + verbose_name=_("Is staff"), + help_text=_("Staff users can log into this admin site."), + ) + is_superuser = models.BooleanField( + default=False, + verbose_name=_("Is superuser"), + help_text=_( + "Superusers have all permissions without explicitly assigning them. Use with caution." + ), + ) + + EMAIL_FIELD = "email" + USERNAME_FIELD = "email" + + def __str__(self): + if self.first_name and self.last_name: + return f"{self.first_name} {self.last_name}" + return self.email + + def normalize_username(self, username): + return super().normalize_username(username).strip().lower() diff --git a/src/servala/settings.py b/src/servala/settings.py index f4a84f9..507d890 100644 --- a/src/servala/settings.py +++ b/src/servala/settings.py @@ -107,6 +107,7 @@ TEMPLATES = [ }, ] +AUTH_USER_MODEL = "core.User" AUTH_PASSWORD_VALIDATORS = [ { "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"