diff --git a/accounts/migrations/0001_initial.py b/accounts/migrations/0001_initial.py index 8009a93..84f8d52 100644 --- a/accounts/migrations/0001_initial.py +++ b/accounts/migrations/0001_initial.py @@ -1,4 +1,5 @@ # Generated by Django 5.2.4 on 2025-07-21 00:54 +from __future__ import annotations import django.contrib.auth.models import django.contrib.auth.validators @@ -7,38 +8,86 @@ from django.db import migrations, models class Migration(migrations.Migration): - initial = True dependencies = [ - ('auth', '0012_alter_user_first_name_max_length'), + ("auth", "0012_alter_user_first_name_max_length"), ] operations = [ migrations.CreateModel( - name='User', + name="User", fields=[ - ('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')), - ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), - ('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')), - ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), - ('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')), - ('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", + ), + ), + ( + "username", + models.CharField( + error_messages={"unique": "A user with that username already exists."}, + help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.", + max_length=150, + unique=True, + validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], + verbose_name="username", + ), + ), + ("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")), + ("email", models.EmailField(blank=True, max_length=254, verbose_name="email address")), + ( + "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")), + ( + "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', - 'db_table': 'auth_user', + "verbose_name": "User", + "verbose_name_plural": "Users", + "db_table": "auth_user", }, managers=[ - ('objects', django.contrib.auth.models.UserManager()), + ("objects", django.contrib.auth.models.UserManager()), ], ), ] diff --git a/accounts/views.py b/accounts/views.py index 5be3c81..4a4f890 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, ClassVar from django.contrib.auth import login from django.contrib.auth.decorators import login_required @@ -36,6 +36,20 @@ class CustomLogoutView(LogoutView): """Custom logout view.""" next_page = reverse_lazy("twitch:dashboard") + http_method_names: ClassVar[list[str]] = ["get", "post", "options"] # pyright: ignore[reportIncompatibleVariableOverride] + + def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: + """Allow GET requests for logout. + + Args: + request: The HTTP request object. + *args: Additional positional arguments. + **kwargs: Additional keyword arguments. + + Returns: + HttpResponse: Response after logout. + """ + return self.post(request, *args, **kwargs) class SignUpView(CreateView): diff --git a/config/settings.py b/config/settings.py index 3bf42b9..d939f7c 100644 --- a/config/settings.py +++ b/config/settings.py @@ -189,10 +189,13 @@ TESTING: bool = "test" in sys.argv or "PYTEST_VERSION" in os.environ if not TESTING: DEBUG_TOOLBAR_CONFIG: dict[str, str] = {"ROOT_TAG_EXTRA_ATTRS": "hx-preserve"} INSTALLED_APPS = [ # pyright: ignore[reportConstantRedefinition] + "django_watchfiles", *INSTALLED_APPS, "debug_toolbar", + "django_browser_reload", ] MIDDLEWARE = [ # pyright: ignore[reportConstantRedefinition] "debug_toolbar.middleware.DebugToolbarMiddleware", *MIDDLEWARE, + "django_browser_reload.middleware.BrowserReloadMiddleware", ] diff --git a/config/urls.py b/config/urls.py index d3adb5a..0d8dde6 100644 --- a/config/urls.py +++ b/config/urls.py @@ -17,4 +17,8 @@ urlpatterns: list[URLResolver] = [ ] if not settings.TESTING: - urlpatterns = [*urlpatterns, *debug_toolbar_urls()] + urlpatterns = [ + *urlpatterns, + *debug_toolbar_urls(), + path("__reload__/", include("django_browser_reload.urls")), + ] diff --git a/pyproject.toml b/pyproject.toml index f208b20..0e7ceeb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,10 @@ readme = "README.md" requires-python = ">=3.13" dependencies = [ "django>=5.2.4", + "django-browser-reload>=1.18.0", "django-debug-toolbar>=5.2.0", + "django-watchfiles>=1.1.0", + "djlint>=1.36.4", "platformdirs>=4.3.8", "python-dotenv>=1.1.1", ] @@ -76,3 +79,7 @@ line-length = 140 "S105", ] "**/migrations/**" = ["RUF012"] + +[tool.djlint] +profile = "django" +ignore = "H021" diff --git a/templates/accounts/login.html b/templates/accounts/login.html index 2d6db3d..adace53 100644 --- a/templates/accounts/login.html +++ b/templates/accounts/login.html @@ -1,66 +1,35 @@ -{% extends 'base.html' %} - -{% block title %}Login{% endblock %} - +{% extends "base.html" %} +{% block title %} + Login +{% endblock title %} {% block content %} -
Member since {{ user.date_joined|date:"F Y" }}
-| Username: | -{{ user.username }} | -
| Email: | -{{ user.email|default:"Not provided" }} | -
| Date Joined: | -{{ user.date_joined|date:"F d, Y" }} | -
| Last Login: | -{{ user.last_login|date:"F d, Y H:i"|default:"Never" }} | -
| Account Status: | -- {% if user.is_active %} - Active - {% else %} - Inactive - {% endif %} - {% if user.is_staff %} - Staff - {% endif %} - {% if user.is_superuser %} - Superuser - {% endif %} - | -
Campaigns Tracked
-Games Followed
-Joined {{ user.date_joined|date:"F d, Y" }}
+| + Date Joined: + | +{{ user.date_joined|date:"F d, Y" }} | +
| + Last Login: + | +{{ user.last_login|date:"F d, Y H:i"|default:"Never" }} | +
| + Email: + | +{{ user.email|default:"Not provided" }} | +
+ Already have an account? Login here +
+{% endblock content %} diff --git a/templates/base.html b/templates/base.html index ab84c0c..9375550 100644 --- a/templates/base.html +++ b/templates/base.html @@ -1,135 +1,41 @@ - - - - -