From 1136e836d233d4c8d76564826d77a567d4482491 Mon Sep 17 00:00:00 2001 From: Michael Herman Date: Sat, 21 Jan 2023 15:04:29 -0600 Subject: [PATCH] updates --- LICENSE | 2 +- README.md | 2 +- .../hello_django/asgi.py | 4 +- .../hello_django/settings.py | 105 +++++++++-------- .../hello_django/urls.py | 9 +- .../hello_django/wsgi.py | 4 +- abstract-base-user-example/manage.py | 4 +- abstract-base-user-example/users/admin.py | 19 +-- abstract-base-user-example/users/apps.py | 4 +- abstract-base-user-example/users/forms.py | 4 +- abstract-base-user-example/users/managers.py | 20 ++-- .../users/migrations/0001_initial.py | 76 +++++++++--- .../migrations/0002_alter_customuser_id.py | 18 --- abstract-base-user-example/users/models.py | 4 +- abstract-base-user-example/users/tests.py | 14 +-- abstract-base-user-example/users/urls.py | 2 +- abstract-base-user-example/users/views.py | 4 +- abstract-user-example/hello_django/asgi.py | 4 +- .../hello_django/settings.py | 105 +++++++++-------- abstract-user-example/hello_django/urls.py | 9 +- abstract-user-example/hello_django/wsgi.py | 4 +- abstract-user-example/manage.py | 4 +- abstract-user-example/users/admin.py | 19 +-- abstract-user-example/users/apps.py | 4 +- abstract-user-example/users/forms.py | 4 +- abstract-user-example/users/managers.py | 20 ++-- .../users/migrations/0001_initial.py | 110 +++++++++++++++--- .../migrations/0002_auto_20210512_2102.py | 23 ---- abstract-user-example/users/models.py | 6 +- abstract-user-example/users/tests.py | 14 +-- abstract-user-example/users/urls.py | 2 +- abstract-user-example/users/views.py | 4 +- 32 files changed, 355 insertions(+), 272 deletions(-) delete mode 100644 abstract-base-user-example/users/migrations/0002_alter_customuser_id.py delete mode 100644 abstract-user-example/users/migrations/0002_auto_20210512_2102.py diff --git a/LICENSE b/LICENSE index 5352154..29812bb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 Michael Herman +Copyright (c) 2023 TestDriven.io Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index cf73074..c4ab526 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Check out the [post](https://testdriven.io/blog/django-custom-user-model/). ```sh $ python3 -m venv env && source env/bin/activate - (env)$ pip install Django==3.2.2 + (env)$ pip install Django (env)$ python manage.py makemigrations (env)$ python manage.py migrate (env)$ python manage.py runserver diff --git a/abstract-base-user-example/hello_django/asgi.py b/abstract-base-user-example/hello_django/asgi.py index c48306c..d6f0ed4 100644 --- a/abstract-base-user-example/hello_django/asgi.py +++ b/abstract-base-user-example/hello_django/asgi.py @@ -4,13 +4,13 @@ It exposes the ASGI callable as a module-level variable named ``application``. For more information on this file, see -https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/ +https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/ """ import os from django.core.asgi import get_asgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hello_django.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hello_django.settings") application = get_asgi_application() diff --git a/abstract-base-user-example/hello_django/settings.py b/abstract-base-user-example/hello_django/settings.py index e909b12..b8473f3 100644 --- a/abstract-base-user-example/hello_django/settings.py +++ b/abstract-base-user-example/hello_django/settings.py @@ -1,13 +1,13 @@ """ Django settings for hello_django project. -Generated by 'django-admin startproject' using Django 3.2.2. +Generated by 'django-admin startproject' using Django 4.1.5. For more information on this file, see -https://docs.djangoproject.com/en/3.2/topics/settings/ +https://docs.djangoproject.com/en/4.1/topics/settings/ For the full list of settings and their values, see -https://docs.djangoproject.com/en/3.2/ref/settings/ +https://docs.djangoproject.com/en/4.1/ref/settings/ """ from pathlib import Path @@ -17,10 +17,10 @@ # Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ +# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'django-insecure-hc2q!paugx$0f0z05&3*9co36qj-o(!!fk=ymz4%5d2drk_jpd' +SECRET_KEY = "django-insecure-#h8#5yy)jsc@sa+r(1t@f^$)(fs(36&q@8l^+&6=c^0r)jk&)4" # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -31,103 +31,102 @@ # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - - 'users', + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + + "users", # new ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", ] -ROOT_URLCONF = 'hello_django.urls' +ROOT_URLCONF = "hello_django.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [ - BASE_DIR / 'templates', + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [ + BASE_DIR / "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', + "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 = 'hello_django.wsgi.application' +WSGI_APPLICATION = "hello_django.wsgi.application" # Database -# https://docs.djangoproject.com/en/3.2/ref/settings/#databases +# https://docs.djangoproject.com/en/4.1/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': BASE_DIR / 'db.sqlite3', + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": BASE_DIR / "db.sqlite3", } } # Password validation -# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators +# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", }, ] # Internationalization -# https://docs.djangoproject.com/en/3.2/topics/i18n/ +# https://docs.djangoproject.com/en/4.1/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = "en-us" -TIME_ZONE = 'UTC' +TIME_ZONE = "UTC" USE_I18N = True -USE_L10N = True - USE_TZ = True # Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/3.2/howto/static-files/ +# https://docs.djangoproject.com/en/4.1/howto/static-files/ -STATIC_URL = '/static/' +STATIC_URL = "static/" # Default primary key field type -# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field +# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +AUTH_USER_MODEL = "users.CustomUser" -AUTH_USER_MODEL = 'users.CustomUser' -LOGIN_REDIRECT_URL = 'home' -LOGOUT_REDIRECT_URL = 'home' +LOGIN_REDIRECT_URL = "home" +LOGOUT_REDIRECT_URL = "home" diff --git a/abstract-base-user-example/hello_django/urls.py b/abstract-base-user-example/hello_django/urls.py index 80a8bdb..829ea6b 100644 --- a/abstract-base-user-example/hello_django/urls.py +++ b/abstract-base-user-example/hello_django/urls.py @@ -2,10 +2,9 @@ from django.urls import path, include from django.views.generic.base import TemplateView - urlpatterns = [ - path('', TemplateView.as_view(template_name='home.html'), name='home'), - path('admin/', admin.site.urls), - path('users/', include('users.urls')), - path('users/', include('django.contrib.auth.urls')), + path("", TemplateView.as_view(template_name="home.html"), name="home"), + path("admin/", admin.site.urls), + path("users/", include("users.urls")), + path("users/", include("django.contrib.auth.urls")), ] diff --git a/abstract-base-user-example/hello_django/wsgi.py b/abstract-base-user-example/hello_django/wsgi.py index 4734281..a5a8ef1 100644 --- a/abstract-base-user-example/hello_django/wsgi.py +++ b/abstract-base-user-example/hello_django/wsgi.py @@ -4,13 +4,13 @@ It exposes the WSGI callable as a module-level variable named ``application``. For more information on this file, see -https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/ +https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/ """ import os from django.core.wsgi import get_wsgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hello_django.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hello_django.settings") application = get_wsgi_application() diff --git a/abstract-base-user-example/manage.py b/abstract-base-user-example/manage.py index b0c067d..7690363 100755 --- a/abstract-base-user-example/manage.py +++ b/abstract-base-user-example/manage.py @@ -6,7 +6,7 @@ def main(): """Run administrative tasks.""" - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hello_django.settings') + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hello_django.settings") try: from django.core.management import execute_from_command_line except ImportError as exc: @@ -18,5 +18,5 @@ def main(): execute_from_command_line(sys.argv) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/abstract-base-user-example/users/admin.py b/abstract-base-user-example/users/admin.py index f0524a9..6a47cfa 100644 --- a/abstract-base-user-example/users/admin.py +++ b/abstract-base-user-example/users/admin.py @@ -9,20 +9,23 @@ class CustomUserAdmin(UserAdmin): add_form = CustomUserCreationForm form = CustomUserChangeForm model = CustomUser - list_display = ('email', 'is_staff', 'is_active',) - list_filter = ('email', 'is_staff', 'is_active',) + list_display = ("email", "is_staff", "is_active",) + list_filter = ("email", "is_staff", "is_active",) fieldsets = ( - (None, {'fields': ('email', 'password')}), - ('Permissions', {'fields': ('is_staff', 'is_active')}), + (None, {"fields": ("email", "password")}), + ("Permissions", {"fields": ("is_staff", "is_active", "groups", "user_permissions")}), ) add_fieldsets = ( (None, { - 'classes': ('wide',), - 'fields': ('email', 'password1', 'password2', 'is_staff', 'is_active')} + "classes": ("wide",), + "fields": ( + "email", "password1", "password2", "is_staff", + "is_active", "groups", "user_permissions" + )} ), ) - search_fields = ('email',) - ordering = ('email',) + search_fields = ("email",) + ordering = ("email",) admin.site.register(CustomUser, CustomUserAdmin) diff --git a/abstract-base-user-example/users/apps.py b/abstract-base-user-example/users/apps.py index 72b1401..88f7b17 100644 --- a/abstract-base-user-example/users/apps.py +++ b/abstract-base-user-example/users/apps.py @@ -2,5 +2,5 @@ class UsersConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'users' + default_auto_field = "django.db.models.BigAutoField" + name = "users" diff --git a/abstract-base-user-example/users/forms.py b/abstract-base-user-example/users/forms.py index a0d55d5..7a8f9a5 100644 --- a/abstract-base-user-example/users/forms.py +++ b/abstract-base-user-example/users/forms.py @@ -7,11 +7,11 @@ class CustomUserCreationForm(UserCreationForm): class Meta: model = CustomUser - fields = ('email',) + fields = ("email",) class CustomUserChangeForm(UserChangeForm): class Meta: model = CustomUser - fields = ('email',) + fields = ("email",) diff --git a/abstract-base-user-example/users/managers.py b/abstract-base-user-example/users/managers.py index e34a4cb..f441f74 100644 --- a/abstract-base-user-example/users/managers.py +++ b/abstract-base-user-example/users/managers.py @@ -1,5 +1,5 @@ from django.contrib.auth.base_user import BaseUserManager -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class CustomUserManager(BaseUserManager): @@ -9,10 +9,10 @@ class CustomUserManager(BaseUserManager): """ def create_user(self, email, password, **extra_fields): """ - Create and save a User with the given email and password. + Create and save a user with the given email and password. """ if not email: - raise ValueError(_('The Email must be set')) + raise ValueError(_("The Email must be set")) email = self.normalize_email(email) user = self.model(email=email, **extra_fields) user.set_password(password) @@ -23,12 +23,12 @@ def create_superuser(self, email, password, **extra_fields): """ Create and save a SuperUser with the given email and password. """ - extra_fields.setdefault('is_staff', True) - extra_fields.setdefault('is_superuser', True) - extra_fields.setdefault('is_active', True) + extra_fields.setdefault("is_staff", True) + extra_fields.setdefault("is_superuser", True) + extra_fields.setdefault("is_active", True) - if extra_fields.get('is_staff') is not True: - raise ValueError(_('Superuser must have is_staff=True.')) - if extra_fields.get('is_superuser') is not True: - raise ValueError(_('Superuser must have is_superuser=True.')) + if extra_fields.get("is_staff") is not True: + raise ValueError(_("Superuser must have is_staff=True.")) + if extra_fields.get("is_superuser") is not True: + raise ValueError(_("Superuser must have is_superuser=True.")) return self.create_user(email, password, **extra_fields) diff --git a/abstract-base-user-example/users/migrations/0001_initial.py b/abstract-base-user-example/users/migrations/0001_initial.py index 69b2f0a..b4a4ff2 100644 --- a/abstract-base-user-example/users/migrations/0001_initial.py +++ b/abstract-base-user-example/users/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.0.4 on 2020-03-13 12:18 +# Generated by Django 4.1.5 on 2023-01-21 21:10 from django.db import migrations, models import django.utils.timezone @@ -9,26 +9,74 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('auth', '0009_alter_user_last_name_max_length'), + ("auth", "0012_alter_user_first_name_max_length"), ] operations = [ migrations.CreateModel( - name='CustomUser', + name="CustomUser", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('password', models.CharField(max_length=128, verbose_name='password')), - ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), - ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), - ('email', models.EmailField(max_length=254, unique=True, verbose_name='email address')), - ('is_staff', models.BooleanField(default=False)), - ('is_active', models.BooleanField(default=True)), - ('date_joined', models.DateTimeField(default=django.utils.timezone.now)), - ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), - ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("password", models.CharField(max_length=128, verbose_name="password")), + ( + "last_login", + models.DateTimeField( + blank=True, null=True, verbose_name="last login" + ), + ), + ( + "is_superuser", + models.BooleanField( + default=False, + help_text="Designates that this user has all permissions without explicitly assigning them.", + verbose_name="superuser status", + ), + ), + ( + "email", + models.EmailField( + max_length=254, unique=True, verbose_name="email address" + ), + ), + ("is_staff", models.BooleanField(default=False)), + ("is_active", models.BooleanField(default=True)), + ( + "date_joined", + models.DateTimeField(default=django.utils.timezone.now), + ), + ( + "groups", + models.ManyToManyField( + blank=True, + help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.", + related_name="user_set", + related_query_name="user", + to="auth.group", + verbose_name="groups", + ), + ), + ( + "user_permissions", + models.ManyToManyField( + blank=True, + help_text="Specific permissions for this user.", + related_name="user_set", + related_query_name="user", + to="auth.permission", + verbose_name="user permissions", + ), + ), ], options={ - 'abstract': False, + "abstract": False, }, ), ] diff --git a/abstract-base-user-example/users/migrations/0002_alter_customuser_id.py b/abstract-base-user-example/users/migrations/0002_alter_customuser_id.py deleted file mode 100644 index aeaf044..0000000 --- a/abstract-base-user-example/users/migrations/0002_alter_customuser_id.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 3.2.2 on 2021-05-12 21:17 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='customuser', - name='id', - field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), - ), - ] diff --git a/abstract-base-user-example/users/models.py b/abstract-base-user-example/users/models.py index 7ac0908..2303e5f 100644 --- a/abstract-base-user-example/users/models.py +++ b/abstract-base-user-example/users/models.py @@ -7,12 +7,12 @@ class CustomUser(AbstractBaseUser, PermissionsMixin): - email = models.EmailField(_('email address'), unique=True) + email = models.EmailField(_("email address"), unique=True) is_staff = models.BooleanField(default=False) is_active = models.BooleanField(default=True) date_joined = models.DateTimeField(default=timezone.now) - USERNAME_FIELD = 'email' + USERNAME_FIELD = "email" REQUIRED_FIELDS = [] objects = CustomUserManager() diff --git a/abstract-base-user-example/users/tests.py b/abstract-base-user-example/users/tests.py index e5dcf77..d5b2fce 100644 --- a/abstract-base-user-example/users/tests.py +++ b/abstract-base-user-example/users/tests.py @@ -6,8 +6,8 @@ class UsersManagersTests(TestCase): def test_create_user(self): User = get_user_model() - user = User.objects.create_user(email='normal@user.com', password='foo') - self.assertEqual(user.email, 'normal@user.com') + user = User.objects.create_user(email="normal@user.com", password="foo") + self.assertEqual(user.email, "normal@user.com") self.assertTrue(user.is_active) self.assertFalse(user.is_staff) self.assertFalse(user.is_superuser) @@ -20,14 +20,14 @@ def test_create_user(self): with self.assertRaises(TypeError): User.objects.create_user() with self.assertRaises(TypeError): - User.objects.create_user(email='') + User.objects.create_user(email="") with self.assertRaises(ValueError): - User.objects.create_user(email='', password="foo") + User.objects.create_user(email="", password="foo") def test_create_superuser(self): User = get_user_model() - admin_user = User.objects.create_superuser(email='super@user.com', password='foo') - self.assertEqual(admin_user.email, 'super@user.com') + admin_user = User.objects.create_superuser(email="super@user.com", password="foo") + self.assertEqual(admin_user.email, "super@user.com") self.assertTrue(admin_user.is_active) self.assertTrue(admin_user.is_staff) self.assertTrue(admin_user.is_superuser) @@ -39,4 +39,4 @@ def test_create_superuser(self): pass with self.assertRaises(ValueError): User.objects.create_superuser( - email='super@user.com', password='foo', is_superuser=False) + email="super@user.com", password="foo", is_superuser=False) diff --git a/abstract-base-user-example/users/urls.py b/abstract-base-user-example/users/urls.py index 84de8f9..fe99b22 100644 --- a/abstract-base-user-example/users/urls.py +++ b/abstract-base-user-example/users/urls.py @@ -2,4 +2,4 @@ from . import views -urlpatterns = [path('signup/', views.SignUp.as_view(), name='signup'), ] +urlpatterns = [path("signup/", views.SignUp.as_view(), name="signup"), ] diff --git a/abstract-base-user-example/users/views.py b/abstract-base-user-example/users/views.py index db9886f..1742312 100644 --- a/abstract-base-user-example/users/views.py +++ b/abstract-base-user-example/users/views.py @@ -6,5 +6,5 @@ class SignUp(generic.CreateView): form_class = CustomUserCreationForm - success_url = reverse_lazy('login') - template_name = 'signup.html' + success_url = reverse_lazy("login") + template_name = "signup.html" diff --git a/abstract-user-example/hello_django/asgi.py b/abstract-user-example/hello_django/asgi.py index c48306c..d6f0ed4 100644 --- a/abstract-user-example/hello_django/asgi.py +++ b/abstract-user-example/hello_django/asgi.py @@ -4,13 +4,13 @@ It exposes the ASGI callable as a module-level variable named ``application``. For more information on this file, see -https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/ +https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/ """ import os from django.core.asgi import get_asgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hello_django.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hello_django.settings") application = get_asgi_application() diff --git a/abstract-user-example/hello_django/settings.py b/abstract-user-example/hello_django/settings.py index 1bf651f..8007318 100644 --- a/abstract-user-example/hello_django/settings.py +++ b/abstract-user-example/hello_django/settings.py @@ -1,13 +1,13 @@ """ Django settings for hello_django project. -Generated by 'django-admin startproject' using Django 3.2.2. +Generated by 'django-admin startproject' using Django 4.1.5. For more information on this file, see -https://docs.djangoproject.com/en/3.2/topics/settings/ +https://docs.djangoproject.com/en/4.1/topics/settings/ For the full list of settings and their values, see -https://docs.djangoproject.com/en/3.2/ref/settings/ +https://docs.djangoproject.com/en/4.1/ref/settings/ """ from pathlib import Path @@ -17,10 +17,10 @@ # Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ +# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'django-insecure-$#^qtosfdgs%$_79!&$!-!hj3fj0*h+f5_nr#7twb2z*a$x+7z' +SECRET_KEY = "django-insecure-epsx)bwj9$%c+fdwjfr!bw&4!6#tu+9@-lov*dh1xj@!i)t$z^" # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -31,103 +31,102 @@ # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - - 'users', + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + + "users", ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", ] -ROOT_URLCONF = 'hello_django.urls' +ROOT_URLCONF = "hello_django.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [ - BASE_DIR / 'templates', + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [ + BASE_DIR / "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', + "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 = 'hello_django.wsgi.application' +WSGI_APPLICATION = "hello_django.wsgi.application" # Database -# https://docs.djangoproject.com/en/3.2/ref/settings/#databases +# https://docs.djangoproject.com/en/4.1/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': BASE_DIR / 'db.sqlite3', + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": BASE_DIR / "db.sqlite3", } } # Password validation -# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators +# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", }, ] # Internationalization -# https://docs.djangoproject.com/en/3.2/topics/i18n/ +# https://docs.djangoproject.com/en/4.1/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = "en-us" -TIME_ZONE = 'UTC' +TIME_ZONE = "UTC" USE_I18N = True -USE_L10N = True - USE_TZ = True # Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/3.2/howto/static-files/ +# https://docs.djangoproject.com/en/4.1/howto/static-files/ -STATIC_URL = '/static/' +STATIC_URL = "static/" # Default primary key field type -# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field +# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +AUTH_USER_MODEL = "users.CustomUser" -AUTH_USER_MODEL = 'users.CustomUser' -LOGIN_REDIRECT_URL = 'home' -LOGOUT_REDIRECT_URL = 'home' +LOGIN_REDIRECT_URL = "home" +LOGOUT_REDIRECT_URL = "home" diff --git a/abstract-user-example/hello_django/urls.py b/abstract-user-example/hello_django/urls.py index 80a8bdb..829ea6b 100644 --- a/abstract-user-example/hello_django/urls.py +++ b/abstract-user-example/hello_django/urls.py @@ -2,10 +2,9 @@ from django.urls import path, include from django.views.generic.base import TemplateView - urlpatterns = [ - path('', TemplateView.as_view(template_name='home.html'), name='home'), - path('admin/', admin.site.urls), - path('users/', include('users.urls')), - path('users/', include('django.contrib.auth.urls')), + path("", TemplateView.as_view(template_name="home.html"), name="home"), + path("admin/", admin.site.urls), + path("users/", include("users.urls")), + path("users/", include("django.contrib.auth.urls")), ] diff --git a/abstract-user-example/hello_django/wsgi.py b/abstract-user-example/hello_django/wsgi.py index 4734281..a5a8ef1 100644 --- a/abstract-user-example/hello_django/wsgi.py +++ b/abstract-user-example/hello_django/wsgi.py @@ -4,13 +4,13 @@ It exposes the WSGI callable as a module-level variable named ``application``. For more information on this file, see -https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/ +https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/ """ import os from django.core.wsgi import get_wsgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hello_django.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hello_django.settings") application = get_wsgi_application() diff --git a/abstract-user-example/manage.py b/abstract-user-example/manage.py index b0c067d..7690363 100755 --- a/abstract-user-example/manage.py +++ b/abstract-user-example/manage.py @@ -6,7 +6,7 @@ def main(): """Run administrative tasks.""" - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hello_django.settings') + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hello_django.settings") try: from django.core.management import execute_from_command_line except ImportError as exc: @@ -18,5 +18,5 @@ def main(): execute_from_command_line(sys.argv) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/abstract-user-example/users/admin.py b/abstract-user-example/users/admin.py index f0524a9..6a47cfa 100644 --- a/abstract-user-example/users/admin.py +++ b/abstract-user-example/users/admin.py @@ -9,20 +9,23 @@ class CustomUserAdmin(UserAdmin): add_form = CustomUserCreationForm form = CustomUserChangeForm model = CustomUser - list_display = ('email', 'is_staff', 'is_active',) - list_filter = ('email', 'is_staff', 'is_active',) + list_display = ("email", "is_staff", "is_active",) + list_filter = ("email", "is_staff", "is_active",) fieldsets = ( - (None, {'fields': ('email', 'password')}), - ('Permissions', {'fields': ('is_staff', 'is_active')}), + (None, {"fields": ("email", "password")}), + ("Permissions", {"fields": ("is_staff", "is_active", "groups", "user_permissions")}), ) add_fieldsets = ( (None, { - 'classes': ('wide',), - 'fields': ('email', 'password1', 'password2', 'is_staff', 'is_active')} + "classes": ("wide",), + "fields": ( + "email", "password1", "password2", "is_staff", + "is_active", "groups", "user_permissions" + )} ), ) - search_fields = ('email',) - ordering = ('email',) + search_fields = ("email",) + ordering = ("email",) admin.site.register(CustomUser, CustomUserAdmin) diff --git a/abstract-user-example/users/apps.py b/abstract-user-example/users/apps.py index 72b1401..88f7b17 100644 --- a/abstract-user-example/users/apps.py +++ b/abstract-user-example/users/apps.py @@ -2,5 +2,5 @@ class UsersConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'users' + default_auto_field = "django.db.models.BigAutoField" + name = "users" diff --git a/abstract-user-example/users/forms.py b/abstract-user-example/users/forms.py index a0d55d5..7a8f9a5 100644 --- a/abstract-user-example/users/forms.py +++ b/abstract-user-example/users/forms.py @@ -7,11 +7,11 @@ class CustomUserCreationForm(UserCreationForm): class Meta: model = CustomUser - fields = ('email',) + fields = ("email",) class CustomUserChangeForm(UserChangeForm): class Meta: model = CustomUser - fields = ('email',) + fields = ("email",) diff --git a/abstract-user-example/users/managers.py b/abstract-user-example/users/managers.py index e34a4cb..f441f74 100644 --- a/abstract-user-example/users/managers.py +++ b/abstract-user-example/users/managers.py @@ -1,5 +1,5 @@ from django.contrib.auth.base_user import BaseUserManager -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ class CustomUserManager(BaseUserManager): @@ -9,10 +9,10 @@ class CustomUserManager(BaseUserManager): """ def create_user(self, email, password, **extra_fields): """ - Create and save a User with the given email and password. + Create and save a user with the given email and password. """ if not email: - raise ValueError(_('The Email must be set')) + raise ValueError(_("The Email must be set")) email = self.normalize_email(email) user = self.model(email=email, **extra_fields) user.set_password(password) @@ -23,12 +23,12 @@ def create_superuser(self, email, password, **extra_fields): """ Create and save a SuperUser with the given email and password. """ - extra_fields.setdefault('is_staff', True) - extra_fields.setdefault('is_superuser', True) - extra_fields.setdefault('is_active', True) + extra_fields.setdefault("is_staff", True) + extra_fields.setdefault("is_superuser", True) + extra_fields.setdefault("is_active", True) - if extra_fields.get('is_staff') is not True: - raise ValueError(_('Superuser must have is_staff=True.')) - if extra_fields.get('is_superuser') is not True: - raise ValueError(_('Superuser must have is_superuser=True.')) + if extra_fields.get("is_staff") is not True: + raise ValueError(_("Superuser must have is_staff=True.")) + if extra_fields.get("is_superuser") is not True: + raise ValueError(_("Superuser must have is_superuser=True.")) return self.create_user(email, password, **extra_fields) diff --git a/abstract-user-example/users/migrations/0001_initial.py b/abstract-user-example/users/migrations/0001_initial.py index a7abd4d..9be1727 100644 --- a/abstract-user-example/users/migrations/0001_initial.py +++ b/abstract-user-example/users/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.0.4 on 2020-03-13 12:18 +# Generated by Django 4.1.5 on 2023-01-21 20:38 from django.db import migrations, models import django.utils.timezone @@ -9,30 +9,104 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('auth', '0009_alter_user_last_name_max_length'), + ("auth", "0012_alter_user_first_name_max_length"), ] operations = [ migrations.CreateModel( - name='CustomUser', + name="CustomUser", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('password', models.CharField(max_length=128, verbose_name='password')), - ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), - ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), - ('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')), - ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), - ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), - ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), - ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), - ('email', models.EmailField(max_length=254, unique=True, verbose_name='email address')), - ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), - ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("password", models.CharField(max_length=128, verbose_name="password")), + ( + "last_login", + models.DateTimeField( + blank=True, null=True, verbose_name="last login" + ), + ), + ( + "is_superuser", + models.BooleanField( + default=False, + help_text="Designates that this user has all permissions without explicitly assigning them.", + verbose_name="superuser status", + ), + ), + ( + "first_name", + models.CharField( + blank=True, max_length=150, verbose_name="first name" + ), + ), + ( + "last_name", + models.CharField( + blank=True, max_length=150, verbose_name="last name" + ), + ), + ( + "is_staff", + models.BooleanField( + default=False, + help_text="Designates whether the user can log into this admin site.", + verbose_name="staff status", + ), + ), + ( + "is_active", + models.BooleanField( + default=True, + help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.", + verbose_name="active", + ), + ), + ( + "date_joined", + models.DateTimeField( + default=django.utils.timezone.now, verbose_name="date joined" + ), + ), + ( + "email", + models.EmailField( + max_length=254, unique=True, verbose_name="email address" + ), + ), + ( + "groups", + models.ManyToManyField( + blank=True, + help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.", + related_name="user_set", + related_query_name="user", + to="auth.group", + verbose_name="groups", + ), + ), + ( + "user_permissions", + models.ManyToManyField( + blank=True, + help_text="Specific permissions for this user.", + related_name="user_set", + related_query_name="user", + to="auth.permission", + verbose_name="user permissions", + ), + ), ], options={ - 'verbose_name': 'user', - 'verbose_name_plural': 'users', - 'abstract': False, + "verbose_name": "user", + "verbose_name_plural": "users", + "abstract": False, }, ), ] diff --git a/abstract-user-example/users/migrations/0002_auto_20210512_2102.py b/abstract-user-example/users/migrations/0002_auto_20210512_2102.py deleted file mode 100644 index 6afa2ad..0000000 --- a/abstract-user-example/users/migrations/0002_auto_20210512_2102.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 3.2.2 on 2021-05-12 21:02 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='customuser', - name='first_name', - field=models.CharField(blank=True, max_length=150, verbose_name='first name'), - ), - migrations.AlterField( - model_name='customuser', - name='id', - field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), - ), - ] diff --git a/abstract-user-example/users/models.py b/abstract-user-example/users/models.py index ed771d6..fca1553 100644 --- a/abstract-user-example/users/models.py +++ b/abstract-user-example/users/models.py @@ -1,15 +1,15 @@ from django.contrib.auth.models import AbstractUser from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from .managers import CustomUserManager class CustomUser(AbstractUser): username = None - email = models.EmailField(_('email address'), unique=True) + email = models.EmailField(_("email address"), unique=True) - USERNAME_FIELD = 'email' + USERNAME_FIELD = "email" REQUIRED_FIELDS = [] objects = CustomUserManager() diff --git a/abstract-user-example/users/tests.py b/abstract-user-example/users/tests.py index e5dcf77..d5b2fce 100644 --- a/abstract-user-example/users/tests.py +++ b/abstract-user-example/users/tests.py @@ -6,8 +6,8 @@ class UsersManagersTests(TestCase): def test_create_user(self): User = get_user_model() - user = User.objects.create_user(email='normal@user.com', password='foo') - self.assertEqual(user.email, 'normal@user.com') + user = User.objects.create_user(email="normal@user.com", password="foo") + self.assertEqual(user.email, "normal@user.com") self.assertTrue(user.is_active) self.assertFalse(user.is_staff) self.assertFalse(user.is_superuser) @@ -20,14 +20,14 @@ def test_create_user(self): with self.assertRaises(TypeError): User.objects.create_user() with self.assertRaises(TypeError): - User.objects.create_user(email='') + User.objects.create_user(email="") with self.assertRaises(ValueError): - User.objects.create_user(email='', password="foo") + User.objects.create_user(email="", password="foo") def test_create_superuser(self): User = get_user_model() - admin_user = User.objects.create_superuser(email='super@user.com', password='foo') - self.assertEqual(admin_user.email, 'super@user.com') + admin_user = User.objects.create_superuser(email="super@user.com", password="foo") + self.assertEqual(admin_user.email, "super@user.com") self.assertTrue(admin_user.is_active) self.assertTrue(admin_user.is_staff) self.assertTrue(admin_user.is_superuser) @@ -39,4 +39,4 @@ def test_create_superuser(self): pass with self.assertRaises(ValueError): User.objects.create_superuser( - email='super@user.com', password='foo', is_superuser=False) + email="super@user.com", password="foo", is_superuser=False) diff --git a/abstract-user-example/users/urls.py b/abstract-user-example/users/urls.py index 143d9dd..faea9e9 100644 --- a/abstract-user-example/users/urls.py +++ b/abstract-user-example/users/urls.py @@ -3,4 +3,4 @@ from . import views -urlpatterns = [path('signup/', views.SignUp.as_view(), name='signup'), ] +urlpatterns = [path("signup/", views.SignUp.as_view(), name="signup"), ] diff --git a/abstract-user-example/users/views.py b/abstract-user-example/users/views.py index db9886f..1742312 100644 --- a/abstract-user-example/users/views.py +++ b/abstract-user-example/users/views.py @@ -6,5 +6,5 @@ class SignUp(generic.CreateView): form_class = CustomUserCreationForm - success_url = reverse_lazy('login') - template_name = 'signup.html' + success_url = reverse_lazy("login") + template_name = "signup.html"