diff --git a/corpus/accounts/admin.py b/corpus/accounts/admin.py index 1ab89cb8..5a5022a6 100644 --- a/corpus/accounts/admin.py +++ b/corpus/accounts/admin.py @@ -2,25 +2,51 @@ from django.contrib.auth.admin import UserAdmin from .models import User -from .forms import CorpusChangeForm # Register your models here. + class CorpusUserAdmin(UserAdmin): fieldsets = ( - (None, {'fields': ('email', 'password')}), - ('Personal Info', {'fields': ('first_name', 'last_name', 'phone_no', 'gender')}), - ('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}), - ('Important dates', {'fields': ('last_login', 'date_joined')}), + (None, {"fields": ("email", "password")}), + ( + "Personal Info", + {"fields": ("first_name", "last_name", "phone_no", "gender")}, + ), + ( + "Permissions", + { + "fields": ( + "is_active", + "is_staff", + "is_superuser", + "groups", + "user_permissions", + ) + }, + ), + ("Important dates", {"fields": ("last_login", "date_joined")}), ) add_fieldsets = ( - (None, { - 'classes': ('wide',), - 'fields': ('email', 'first_name', 'last_name', 'phone_no', 'gender', 'password1', 'password2'), - }), + ( + None, + { + "classes": ("wide",), + "fields": ( + "email", + "first_name", + "last_name", + "phone_no", + "gender", + "password1", + "password2", + ), + }, + ), ) - list_display = ('email', 'first_name', 'last_name', 'phone_no', 'gender') - search_fields = ('email', 'first_name', 'last_name', 'phone_no') - ordering = ('email',) + list_display = ("email", "first_name", "last_name", "phone_no", "gender") + search_fields = ("email", "first_name", "last_name", "phone_no") + ordering = ("email",) + -admin.site.register(User, CorpusUserAdmin) \ No newline at end of file +admin.site.register(User, CorpusUserAdmin) diff --git a/corpus/accounts/apps.py b/corpus/accounts/apps.py index 3e3c7659..0cb51e63 100644 --- a/corpus/accounts/apps.py +++ b/corpus/accounts/apps.py @@ -2,5 +2,5 @@ class AccountsConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'accounts' + default_auto_field = "django.db.models.BigAutoField" + name = "accounts" diff --git a/corpus/accounts/backend.py b/corpus/accounts/backend.py index ccd6f165..8a8a058a 100644 --- a/corpus/accounts/backend.py +++ b/corpus/accounts/backend.py @@ -1,6 +1,7 @@ from django.contrib.auth import get_user_model from django.contrib.auth.backends import ModelBackend + class CorpusAuthBackend(ModelBackend): def authenticate(self, request, username=None, password=None, **kwargs): UserModel = get_user_model() @@ -12,10 +13,10 @@ def authenticate(self, request, username=None, password=None, **kwargs): if user.check_password(password): return user return None - + def get_user(self, user_id): UserModel = get_user_model() try: return UserModel.objects.get(pk=user_id) except UserModel.DoesNotExist: - return None \ No newline at end of file + return None diff --git a/corpus/accounts/forms.py b/corpus/accounts/forms.py index cc674746..6ae0471e 100644 --- a/corpus/accounts/forms.py +++ b/corpus/accounts/forms.py @@ -1,13 +1,18 @@ from django import forms -from django.contrib.auth.forms import UserCreationForm, UserChangeForm, AuthenticationForm -from .models import User, GENDERS +from django.contrib.auth.forms import AuthenticationForm +from django.contrib.auth.forms import UserChangeForm +from django.contrib.auth.forms import UserCreationForm + +from .models import GENDERS +from .models import User + class CorpusCreationForm(UserCreationForm): phone_no = forms.CharField(required=True) gender = forms.ChoiceField(choices=GENDERS, required=True) error_css_class = "text-sm text-error" - + class Meta: model = User fields = [ @@ -17,18 +22,21 @@ class Meta: "gender", "email", "password1", - "password2" + "password2", ] def __init__(self, *args, **kwargs): super(CorpusCreationForm, self).__init__(*args, **kwargs) for visible in self.visible_fields(): - visible.field.widget.attrs["class"] = "mt-1 block w-full rounded-md border-base-800 text-black shadow-sm focus:border-primary focus:ring focus:ring-primary-200 focus:ring-opacity-50" + visible.field.widget.attrs[ + "class" + ] = "mt-1 block w-full rounded-md border-base-800 text-black shadow-sm focus:border-primary focus:ring focus:ring-primary-200 focus:ring-opacity-50" # noqa: E501 + class CorpusChangeForm(UserChangeForm): phone_no = forms.CharField(required=True) gender = forms.ChoiceField(choices=GENDERS, required=True) - + class Meta: model = User fields = [ @@ -39,14 +47,17 @@ class Meta: "email", ] + class CorpusLoginForm(AuthenticationForm): def __init__(self, *args, **kwargs): super(CorpusLoginForm, self).__init__(*args, **kwargs) for visible in self.visible_fields(): - visible.field.widget.attrs["class"] = "mt-1 block w-full rounded-md border-base-800 text-black shadow-sm focus:border-primary focus:ring focus:ring-primary-200 focus:ring-opacity-50" + visible.field.widget.attrs[ + "class" + ] = "mt-1 block w-full rounded-md border-base-800 text-black shadow-sm focus:border-primary focus:ring focus:ring-primary-200 focus:ring-opacity-50" # noqa: E501 def clean_username(self): - username = self.cleaned_data.get('username') + username = self.cleaned_data.get("username") if username: username = username.lower() - return username \ No newline at end of file + return username diff --git a/corpus/accounts/migrations/0001_initial.py b/corpus/accounts/migrations/0001_initial.py index 6cafe16c..db5ae72a 100644 --- a/corpus/accounts/migrations/0001_initial.py +++ b/corpus/accounts/migrations/0001_initial.py @@ -1,7 +1,7 @@ # Generated by Django 4.2.4 on 2023-09-07 15:06 - -from django.db import migrations, models import django.utils.timezone +from django.db import migrations +from django.db import models class Migration(migrations.Migration): @@ -9,32 +9,112 @@ 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')), - ('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')), - ('phone_no', models.CharField(max_length=13, unique=True)), - ('gender', models.CharField(choices=[('M', 'Male'), ('F', 'Female'), ('O', 'Other'), ('N', 'Prefer not to disclose')], max_length=1)), - ('email', models.EmailField(max_length=254, unique=True)), - ('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" + ), + ), + ("phone_no", models.CharField(max_length=13, unique=True)), + ( + "gender", + models.CharField( + choices=[ + ("M", "Male"), + ("F", "Female"), + ("O", "Other"), + ("N", "Prefer not to disclose"), + ], + max_length=1, + ), + ), + ("email", models.EmailField(max_length=254, unique=True)), + ( + "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/corpus/accounts/models.py b/corpus/accounts/models.py index bb38a391..1f98fe7c 100644 --- a/corpus/accounts/models.py +++ b/corpus/accounts/models.py @@ -1,6 +1,6 @@ -from django.db import models -from django.contrib.auth.models import AbstractUser from django.contrib.auth.base_user import BaseUserManager +from django.contrib.auth.models import AbstractUser +from django.db import models from django.utils.translation import gettext_lazy as _ # Create your models here. @@ -12,17 +12,18 @@ ("N", "Prefer not to disclose"), ] + class UserManager(BaseUserManager): def create_user(self, email, password, **kwargs): if not email: raise ValueError(_("Email must be set.")) - + email = self.normalize_email(email) user = self.model(email=email, **kwargs) user.set_password(password) user.save() return user - + def create_superuser(self, email, password, **kwargs): kwargs.setdefault("is_staff", True) kwargs.setdefault("is_superuser", True) @@ -33,10 +34,11 @@ def create_superuser(self, email, password, **kwargs): if kwargs.get("is_superuser") is not True: raise ValueError(_("Superuser must have is_superuser=True.")) return self.create_user(email, password, **kwargs) - + def users(self): return self.filter(is_active=True) + class User(AbstractUser): username = None phone_no = models.CharField(max_length=13, unique=True, blank=False, null=False) @@ -49,4 +51,4 @@ class User(AbstractUser): objects = UserManager() def __str__(self): - return f"{self.first_name} {self.last_name}" \ No newline at end of file + return f"{self.first_name} {self.last_name}" diff --git a/corpus/accounts/urls.py b/corpus/accounts/urls.py index 398187bd..6c291ade 100644 --- a/corpus/accounts/urls.py +++ b/corpus/accounts/urls.py @@ -1,8 +1,11 @@ from django.urls import path -from .views import signup, signin, signout + +from .views import signin +from .views import signout +from .views import signup urlpatterns = [ path("signup/", signup, name="accounts_signup"), path("login/", signin, name="accounts_signin"), - path("logout/", signout, name="accounts_signout") -] \ No newline at end of file + path("logout/", signout, name="accounts_signout"), +] diff --git a/corpus/accounts/views.py b/corpus/accounts/views.py index 6596ff46..3b310964 100644 --- a/corpus/accounts/views.py +++ b/corpus/accounts/views.py @@ -1,24 +1,30 @@ -from django.shortcuts import render, redirect -from django.contrib.auth import login, authenticate, logout from django.contrib import messages -from .forms import CorpusCreationForm, CorpusLoginForm +from django.contrib.auth import login +from django.contrib.auth import logout +from django.shortcuts import redirect +from django.shortcuts import render + +from .forms import CorpusCreationForm +from .forms import CorpusLoginForm # Create your views here. + def signup(request): if request.method == "POST": form = CorpusCreationForm(request.POST) if form.is_valid(): form.save() - messages.success(request, "You have been successfully registered. Please sign in!") + messages.success( + request, "You have been successfully registered. Please sign in!" + ) return redirect("accounts_signin") else: form = CorpusCreationForm() - args = { - "form": form - } + args = {"form": form} return render(request, "accounts/signup.html", args) + def signin(request): if request.method == "POST": form = CorpusLoginForm(request, data=request.POST) @@ -30,12 +36,11 @@ def signin(request): else: form = CorpusLoginForm() - args = { - "form": form - } + args = {"form": form} return render(request, "accounts/login.html", args) + def signout(request): logout(request) messages.success(request, "Successfully signed out.") - return redirect("index") \ No newline at end of file + return redirect("index") diff --git a/corpus/corpus/settings.py b/corpus/corpus/settings.py index 34122c27..75306c35 100644 --- a/corpus/corpus/settings.py +++ b/corpus/corpus/settings.py @@ -165,4 +165,4 @@ LOGIN_URL = "/accounts/login" LOGIN_REDIRECT_URL = "/" LOGOUT_URL = "" -LOGOUT_REDIRECT_URL = "/" \ No newline at end of file +LOGOUT_REDIRECT_URL = "/" diff --git a/corpus/corpus/urls.py b/corpus/corpus/urls.py index 6a788664..8501e8c7 100644 --- a/corpus/corpus/urls.py +++ b/corpus/corpus/urls.py @@ -21,5 +21,5 @@ urlpatterns = [ path("admin/", admin.site.urls), path("", include("pages.urls")), - path("accounts/", include("accounts.urls")) + path("accounts/", include("accounts.urls")), ] diff --git a/corpus/templates/accounts/login.html b/corpus/templates/accounts/login.html index c2d9daf0..ad981c6b 100644 --- a/corpus/templates/accounts/login.html +++ b/corpus/templates/accounts/login.html @@ -8,7 +8,7 @@

Login

- +
{% csrf_token %} @@ -33,4 +33,4 @@

Login

If you don't have an account, register here.

-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/corpus/templates/accounts/signup.html b/corpus/templates/accounts/signup.html index d6d36ba4..ba2cfb68 100644 --- a/corpus/templates/accounts/signup.html +++ b/corpus/templates/accounts/signup.html @@ -8,7 +8,7 @@

Sign up

- + {% csrf_token %} @@ -29,4 +29,4 @@

Sign up

If you already have an account, login instead.

-{% endblock %} \ No newline at end of file +{% endblock %}