diff --git a/accounts/filters.py b/accounts/filters.py new file mode 100644 index 0000000..6c54d34 --- /dev/null +++ b/accounts/filters.py @@ -0,0 +1,71 @@ +from django.db.models import Q +import django_filters +from .models import User, Student + + +class LecturerFilter(django_filters.FilterSet): + username = django_filters.CharFilter(lookup_expr="exact", label="") + name = django_filters.CharFilter(method="filter_by_name", label="") + email = django_filters.CharFilter(lookup_expr="icontains", label="") + + class Meta: + model = User + fields = ["username", "email"] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Change html classes and placeholders + self.filters["username"].field.widget.attrs.update( + {"class": "au-input", "placeholder": "ID No."} + ) + self.filters["name"].field.widget.attrs.update( + {"class": "au-input", "placeholder": "Name"} + ) + self.filters["email"].field.widget.attrs.update( + {"class": "au-input", "placeholder": "Email"} + ) + + def filter_by_name(self, queryset, name, value): + return queryset.filter( + Q(first_name__icontains=value) | Q(last_name__icontains=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="") + department__title = django_filters.CharFilter(lookup_expr="icontains", label="") + + class Meta: + model = Student + fields = [ + "student__username", + "student__name", + "student__email", + "department__title", + ] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Change html classes and placeholders + self.filters["student__username"].field.widget.attrs.update( + {"class": "au-input", "placeholder": "ID No."} + ) + self.filters["student__name"].field.widget.attrs.update( + {"class": "au-input", "placeholder": "Name"} + ) + self.filters["student__email"].field.widget.attrs.update( + {"class": "au-input", "placeholder": "Email"} + ) + self.filters["department__title"].field.widget.attrs.update( + {"class": "au-input", "placeholder": "Department"} + ) + + def filter_by_name(self, queryset, name, value): + return queryset.filter( + Q(student__first_name__icontains=value) + | Q(student__last_name__icontains=value) + ) diff --git a/accounts/urls.py b/accounts/urls.py index a387ae0..edfc697 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -14,7 +14,7 @@ from .views import ( admin_panel, profile_update, change_password, - LecturerListView, + LecturerFilterView, StudentListView, staff_add_view, edit_staff, @@ -37,7 +37,7 @@ urlpatterns = [ path("profile//detail/", profile_single, name="profile_single"), path("setting/", profile_update, name="edit_profile"), path("change_password/", change_password, name="change_password"), - path("lecturers/", LecturerListView.as_view(), name="lecturer_list"), + path("lecturers/", LecturerFilterView.as_view(), name="lecturer_list"), path("lecturer/add/", staff_add_view, name="add_lecturer"), path("staff//edit/", edit_staff, name="staff_edit"), path("lecturers//delete/", delete_staff, name="lecturer_delete"), diff --git a/accounts/views.py b/accounts/views.py index 3c4aa18..246c1ca 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -7,12 +7,14 @@ from django.views.generic import CreateView, ListView from django.db.models import Q from django.utils.decorators import method_decorator from django.contrib.auth.forms import PasswordChangeForm +from django_filters.views import FilterView from core.models import Session, Semester from course.models import Course from result.models import TakenCourse from .decorators import admin_required from .forms import StaffAddForm, StudentAddForm, ProfileUpdateForm, ParentAddForm from .models import User, Student, Parent +from .filters import LecturerFilter, StudentFilter def validate_username(request): @@ -259,7 +261,8 @@ def edit_staff(request, pk): @method_decorator([login_required, admin_required], name="dispatch") -class LecturerListView(ListView): +class LecturerFilterView(FilterView): + filterset_class = LecturerFilter queryset = User.objects.filter(is_lecturer=True) template_name = "accounts/lecturer_list.html" paginate_by = 10 # if pagination is desired @@ -348,16 +351,10 @@ def edit_student(request, pk): @method_decorator([login_required, admin_required], name="dispatch") -class StudentListView(ListView): +class StudentListView(FilterView): + filterset_class = StudentFilter template_name = "accounts/student_list.html" - paginate_by = 10 # if pagination is desired - - def get_queryset(self): - queryset = Student.objects.all() - query = self.request.GET.get("student_id") - if query is not None: - queryset = queryset.filter(Q(department=query)) - return queryset + paginate_by = 10 def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) diff --git a/config/settings.py b/config/settings.py index 809e68d..d01178e 100644 --- a/config/settings.py +++ b/config/settings.py @@ -49,6 +49,7 @@ DJANGO_APPS = [ THIRD_PARTY_APPS = [ "crispy_forms", "rest_framework", + "django_filters", ] # Custom apps diff --git a/requirements/base.txt b/requirements/base.txt index 76a65b6..9970d33 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -15,6 +15,7 @@ django-crispy-forms==1.14.0 # https://github.com/django-crispy-forms/django-cri crispy-bootstrap5==0.7 # https://github.com/django-crispy-forms/crispy-bootstrap5 django-compressor==4.1 # https://github.com/django-compressor/django-compressor django-redis==5.2.0 # https://github.com/jazzband/django-redis +django-filter==23.5 # https://github.com/carltongibson/django-filter # Django REST Framework djangorestframework==3.14.0 # https://github.com/encode/django-rest-framework django-cors-headers==3.13.0 # https://github.com/adamchainz/django-cors-headers diff --git a/templates/accounts/lecturer_list.html b/templates/accounts/lecturer_list.html index 25be0c2..eb97ddc 100644 --- a/templates/accounts/lecturer_list.html +++ b/templates/accounts/lecturer_list.html @@ -29,11 +29,9 @@
- - - + {{ filter.form }}
@@ -55,7 +53,7 @@ - {% for lecturer in object_list %} + {% for lecturer in filter.qs %} {{ forloop.counter }}. {{ lecturer.username }} diff --git a/templates/accounts/student_list.html b/templates/accounts/student_list.html index 3417f2c..6f18517 100644 --- a/templates/accounts/student_list.html +++ b/templates/accounts/student_list.html @@ -29,11 +29,9 @@
- - - + {{ filter.form }}
@@ -63,7 +61,7 @@ - {% for student in object_list %} + {% for student in filter.qs %} {{ forloop.counter }}. {{ student.student.username }}