diff --git a/accounts/filters.py b/accounts/filters.py index 3960888..d24fd85 100644 --- a/accounts/filters.py +++ b/accounts/filters.py @@ -33,34 +33,42 @@ def filter_by_name(self, queryset, name, value): class StudentFilter(django_filters.FilterSet): - student__username = django_filters.CharFilter(lookup_expr="exact", label="") - student__name = django_filters.CharFilter(method="filter_by_name", label="") - student__email = django_filters.CharFilter(lookup_expr="icontains", label="") - program__title = django_filters.CharFilter(lookup_expr="icontains", label="") + id_no = django_filters.CharFilter( + field_name="student__username", lookup_expr="exact", label="" + ) + name = django_filters.CharFilter( + field_name="student__name", method="filter_by_name", label="" + ) + email = django_filters.CharFilter( + field_name="student__email", lookup_expr="icontains", label="" + ) + program = django_filters.CharFilter( + field_name="student__program", lookup_expr="icontains", label="" + ) class Meta: model = Student fields = [ - "student__username", - "student__name", - "student__email", - "program__title", + "id_no", + "name", + "email", + "program", ] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Change html classes and placeholders - self.filters["student__username"].field.widget.attrs.update( + self.filters["id_no"].field.widget.attrs.update( {"class": "au-input", "placeholder": "ID No."} ) - self.filters["student__name"].field.widget.attrs.update( + self.filters["name"].field.widget.attrs.update( {"class": "au-input", "placeholder": "Name"} ) - self.filters["student__email"].field.widget.attrs.update( + self.filters["email"].field.widget.attrs.update( {"class": "au-input", "placeholder": "Email"} ) - self.filters["program__title"].field.widget.attrs.update( + self.filters["program"].field.widget.attrs.update( {"class": "au-input", "placeholder": "Program"} ) diff --git a/accounts/forms.py b/accounts/forms.py index 8ddc872..6cbdaec 100644 --- a/accounts/forms.py +++ b/accounts/forms.py @@ -118,22 +118,16 @@ def save(self, commit=True): user.address = self.cleaned_data.get("address") user.email = self.cleaned_data.get("email") - # Generate a username based on first and last name and registration date - registration_date = datetime.now().strftime("%Y%m%d%H%M") + # Generate a username + registration_date = datetime.now().strftime("%Y") + total_lecturers_count = User.objects.filter(is_lecturer=True).count() generated_username = ( - f"{user.first_name.lower()}{user.last_name.lower()}{registration_date}" + f"{settings.LECTURER_ID_PREFIX}-{registration_date}-{total_lecturers_count}" ) - - # Check if the generated username already exists, and regenerate if needed - while User.objects.filter(username=generated_username).exists(): - registration_date = datetime.now().strftime("%Y%m%d%H%M") - generated_username = f"{user.first_name.lower()}{user.last_name.lower()}{registration_date}".replace( - " ", "" - ) + # Generate a password + generated_password = User.objects.make_random_password() user.username = generated_username - - generated_password = User.objects.make_random_password() user.set_password(generated_password) if commit: @@ -141,7 +135,7 @@ def save(self, commit=True): # Send email with the generated credentials send_mail( - "Your account credentials", + "Your Django LMS account credentials", f"Your username: {generated_username}\nYour password: {generated_password}", "from@example.com", [user.email], @@ -285,30 +279,29 @@ def save(self, commit=True): user.email = self.cleaned_data.get("email") # Generate a username based on first and last name and registration date - registration_date = datetime.now().strftime("%Y%m%d%H%M") + registration_date = datetime.now().strftime("%Y") + total_students_count = Student.objects.count() generated_username = ( - f"{user.first_name.lower()}{user.last_name.lower()}{registration_date}" + f"{settings.STUDENT_ID_PREFIX}-{registration_date}-{total_students_count}" ) - - # Check if the generated username already exists, and regenerate if needed - while User.objects.filter(username=generated_username).exists(): - registration_date = datetime.now().strftime("%Y%m%d%H%M") - generated_username = f"{user.first_name.lower()}{user.last_name.lower()}{registration_date}".replace( - " ", "" - ) + # Generate a password + generated_password = User.objects.make_random_password() user.username = generated_username - - generated_password = User.objects.make_random_password() user.set_password(generated_password) if commit: user.save() + Student.objects.create( + student=user, + level=self.cleaned_data.get("level"), + program=self.cleaned_data.get("program"), + ) # Send email with the generated credentials send_mail( - "Your account credentials", - f"Your username: {generated_username}\nYour password: {generated_password}", + "Your Django LMS account credentials", + f"Your ID: {generated_username}\nYour password: {generated_password}", settings.EMAIL_FROM_ADDRESS, [user.email], fail_silently=False, @@ -348,6 +341,15 @@ class ProfileUpdateForm(UserChangeForm): label="Last Name", ) + gender = forms.CharField( + widget=forms.Select( + choices=GENDERS, + attrs={ + "class": "browser-default custom-select form-control", + }, + ), + ) + phone = forms.CharField( widget=forms.TextInput( attrs={ @@ -370,7 +372,15 @@ class ProfileUpdateForm(UserChangeForm): class Meta: model = User - fields = ["email", "phone", "address", "picture", "first_name", "last_name"] + fields = [ + "first_name", + "last_name", + "gender", + "email", + "phone", + "address", + "picture", + ] class EmailValidationOnForgotPassword(PasswordResetForm): diff --git a/accounts/models.py b/accounts/models.py index 23e5906..3fb6c22 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -54,6 +54,15 @@ def search(self, query=None): ).distinct() # distinct() is often necessary with Q lookups return queryset + def get_student_count(self): + return self.model.objects.filter(is_student=True).count() + + def get_lecturer_count(self): + return self.model.objects.filter(is_lecturer=True).count() + + def get_superuser_count(self): + return self.model.objects.filter(is_superuser=True).count() + GENDERS = (("M", "Male"), ("F", "Female")) @@ -85,18 +94,6 @@ def get_full_name(self): full_name = self.first_name + " " + self.last_name return full_name - @classmethod - def get_student_count(cls): - return cls.objects.filter(is_student=True).count() - - @classmethod - def get_lecturer_count(cls): - return cls.objects.filter(is_lecturer=True).count() - - @classmethod - def get_superuser_count(cls): - return cls.objects.filter(is_superuser=True).count() - def __str__(self): return "{} ({})".format(self.username, self.get_full_name) diff --git a/accounts/signals.py b/accounts/signals.py new file mode 100644 index 0000000..e69de29 diff --git a/accounts/views.py b/accounts/views.py index 010991c..83f7501 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -212,9 +212,9 @@ def staff_add_view(request): form = StaffAddForm(request.POST) first_name = request.POST.get("first_name") last_name = request.POST.get("last_name") - + if form.is_valid(): - + form.save() messages.success( request, @@ -354,6 +354,7 @@ def edit_student(request, pk): @method_decorator([login_required, admin_required], name="dispatch") class StudentListView(FilterView): + queryset = Student.objects.all() filterset_class = StudentFilter template_name = "accounts/student_list.html" paginate_by = 10 diff --git a/config/settings.py b/config/settings.py index a7f6d17..53a3577 100644 --- a/config/settings.py +++ b/config/settings.py @@ -192,13 +192,11 @@ EMAIL_BACKEND = config( "EMAIL_BACKEND", default="django.core.mail.backends.smtp.EmailBackend" ) -EMAIL_HOST = config( - "EMAIL_HOST", default="smtp.gmail.com" -) # Gmail as the email host, but you can change it +EMAIL_HOST = config("EMAIL_HOST", default="smtp.gmail.com") EMAIL_PORT = config("EMAIL_PORT", default=587) EMAIL_USE_TLS = True -EMAIL_HOST_USER = config("USER_EMAIL") -EMAIL_HOST_PASSWORD = config("USER_PASSWORD") +EMAIL_HOST_USER = config("EMAIL_HOST_USER") +EMAIL_HOST_PASSWORD = config("EMAIL_HOST_PASSWORD") EMAIL_FROM_ADDRESS = config("EMAIL_FROM_ADDRESS") # crispy config @@ -249,3 +247,6 @@ # WhiteNoise configuration STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" + +STUDENT_ID_PREFIX = config("STUDENT_ID_PREFIX", "ugr") +LECTURER_ID_PREFIX = config("LECTURER_ID_PREFIX", "lec") diff --git a/core/views.py b/core/views.py index 241d290..5858148 100644 --- a/core/views.py +++ b/core/views.py @@ -1,12 +1,11 @@ from django.shortcuts import render, redirect, get_object_or_404 from django.contrib import messages from django.contrib.auth.decorators import login_required -from django.conf import settings from accounts.decorators import admin_required, lecturer_required from accounts.models import User, Student from .forms import SessionForm, SemesterForm, NewsAndEventsForm -from .models import * +from .models import NewsAndEvents, ActivityLog, Session, Semester # ######################################################## @@ -28,9 +27,9 @@ def dashboard_view(request): logs = ActivityLog.objects.all().order_by("-created_at")[:10] gender_count = Student.get_gender_count() context = { - "student_count": User.get_student_count(), - "lecturer_count": User.get_lecturer_count(), - "superuser_count": User.get_superuser_count(), + "student_count": User.objects.get_student_count(), + "lecturer_count": User.objects.get_lecturer_count(), + "superuser_count": User.objects.get_superuser_count(), "males_count": gender_count["M"], "females_count": gender_count["F"], "logs": logs, diff --git a/templates/accounts/edit_student.html b/templates/accounts/edit_student.html index ed7e445..8a56495 100644 --- a/templates/accounts/edit_student.html +++ b/templates/accounts/edit_student.html @@ -27,6 +27,7 @@
Lecturers
-{% if messages %} - {% for message in messages %} - {% if message.tags == 'error' %} -