Merge pull request #12 from benaissazaki/add-filters-to-tables
Add filters to tables
This commit is contained in:
commit
ea75bc29dd
71
accounts/filters.py
Normal file
71
accounts/filters.py
Normal file
@ -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)
|
||||||
|
)
|
||||||
@ -14,7 +14,7 @@ from .views import (
|
|||||||
admin_panel,
|
admin_panel,
|
||||||
profile_update,
|
profile_update,
|
||||||
change_password,
|
change_password,
|
||||||
LecturerListView,
|
LecturerFilterView,
|
||||||
StudentListView,
|
StudentListView,
|
||||||
staff_add_view,
|
staff_add_view,
|
||||||
edit_staff,
|
edit_staff,
|
||||||
@ -37,7 +37,7 @@ urlpatterns = [
|
|||||||
path("profile/<int:id>/detail/", profile_single, name="profile_single"),
|
path("profile/<int:id>/detail/", profile_single, name="profile_single"),
|
||||||
path("setting/", profile_update, name="edit_profile"),
|
path("setting/", profile_update, name="edit_profile"),
|
||||||
path("change_password/", change_password, name="change_password"),
|
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("lecturer/add/", staff_add_view, name="add_lecturer"),
|
||||||
path("staff/<int:pk>/edit/", edit_staff, name="staff_edit"),
|
path("staff/<int:pk>/edit/", edit_staff, name="staff_edit"),
|
||||||
path("lecturers/<int:pk>/delete/", delete_staff, name="lecturer_delete"),
|
path("lecturers/<int:pk>/delete/", delete_staff, name="lecturer_delete"),
|
||||||
|
|||||||
@ -7,12 +7,14 @@ from django.views.generic import CreateView, ListView
|
|||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
from django.contrib.auth.forms import PasswordChangeForm
|
from django.contrib.auth.forms import PasswordChangeForm
|
||||||
|
from django_filters.views import FilterView
|
||||||
from core.models import Session, Semester
|
from core.models import Session, Semester
|
||||||
from course.models import Course
|
from course.models import Course
|
||||||
from result.models import TakenCourse
|
from result.models import TakenCourse
|
||||||
from .decorators import admin_required
|
from .decorators import admin_required
|
||||||
from .forms import StaffAddForm, StudentAddForm, ProfileUpdateForm, ParentAddForm
|
from .forms import StaffAddForm, StudentAddForm, ProfileUpdateForm, ParentAddForm
|
||||||
from .models import User, Student, Parent
|
from .models import User, Student, Parent
|
||||||
|
from .filters import LecturerFilter, StudentFilter
|
||||||
|
|
||||||
|
|
||||||
def validate_username(request):
|
def validate_username(request):
|
||||||
@ -259,7 +261,8 @@ def edit_staff(request, pk):
|
|||||||
|
|
||||||
|
|
||||||
@method_decorator([login_required, admin_required], name="dispatch")
|
@method_decorator([login_required, admin_required], name="dispatch")
|
||||||
class LecturerListView(ListView):
|
class LecturerFilterView(FilterView):
|
||||||
|
filterset_class = LecturerFilter
|
||||||
queryset = User.objects.filter(is_lecturer=True)
|
queryset = User.objects.filter(is_lecturer=True)
|
||||||
template_name = "accounts/lecturer_list.html"
|
template_name = "accounts/lecturer_list.html"
|
||||||
paginate_by = 10 # if pagination is desired
|
paginate_by = 10 # if pagination is desired
|
||||||
@ -348,16 +351,10 @@ def edit_student(request, pk):
|
|||||||
|
|
||||||
|
|
||||||
@method_decorator([login_required, admin_required], name="dispatch")
|
@method_decorator([login_required, admin_required], name="dispatch")
|
||||||
class StudentListView(ListView):
|
class StudentListView(FilterView):
|
||||||
|
filterset_class = StudentFilter
|
||||||
template_name = "accounts/student_list.html"
|
template_name = "accounts/student_list.html"
|
||||||
paginate_by = 10 # if pagination is desired
|
paginate_by = 10
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
|
|||||||
@ -49,6 +49,7 @@ DJANGO_APPS = [
|
|||||||
THIRD_PARTY_APPS = [
|
THIRD_PARTY_APPS = [
|
||||||
"crispy_forms",
|
"crispy_forms",
|
||||||
"rest_framework",
|
"rest_framework",
|
||||||
|
"django_filters",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Custom apps
|
# Custom apps
|
||||||
|
|||||||
@ -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
|
crispy-bootstrap5==0.7 # https://github.com/django-crispy-forms/crispy-bootstrap5
|
||||||
django-compressor==4.1 # https://github.com/django-compressor/django-compressor
|
django-compressor==4.1 # https://github.com/django-compressor/django-compressor
|
||||||
django-redis==5.2.0 # https://github.com/jazzband/django-redis
|
django-redis==5.2.0 # https://github.com/jazzband/django-redis
|
||||||
|
django-filter==23.5 # https://github.com/carltongibson/django-filter
|
||||||
# Django REST Framework
|
# Django REST Framework
|
||||||
djangorestframework==3.14.0 # https://github.com/encode/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
|
django-cors-headers==3.13.0 # https://github.com/adamchainz/django-cors-headers
|
||||||
|
|||||||
@ -29,11 +29,9 @@
|
|||||||
|
|
||||||
<div class="content-center">
|
<div class="content-center">
|
||||||
<form class="search-form" action="" method="get">
|
<form class="search-form" action="" method="get">
|
||||||
<input class="au-input" type="text" name="id_no" placeholder="ID No." value="{{ request.GET.id_no }}"/>
|
{{ filter.form }}
|
||||||
<input class="au-input" type="text" name="name" placeholder="Name" value="{{ request.GET.name }}"/>
|
|
||||||
<input class="au-input" type="text" name="email" placeholder="Email" value="{{ request.GET.email }}"/>
|
|
||||||
<button class="btn btn-light" type="submit">
|
<button class="btn btn-light" type="submit">
|
||||||
<i class="fas fa-search"></i> filter
|
<i class="fas fa-search"></i> Filter
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -55,7 +53,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for lecturer in object_list %}
|
{% for lecturer in filter.qs %}
|
||||||
<tr>
|
<tr>
|
||||||
<td> {{ forloop.counter }}.</td>
|
<td> {{ forloop.counter }}.</td>
|
||||||
<td>{{ lecturer.username }}</td>
|
<td>{{ lecturer.username }}</td>
|
||||||
|
|||||||
@ -29,11 +29,9 @@
|
|||||||
|
|
||||||
<div class="content-center">
|
<div class="content-center">
|
||||||
<form class="search-form" action="" method="get">
|
<form class="search-form" action="" method="get">
|
||||||
<input class="au-input" type="text" id="student_id" name="student_id" placeholder="ID No." value="{{ request.GET.student_id }}"/>
|
{{ filter.form }}
|
||||||
<input class="au-input" type="text" name="name" placeholder="Name" value="{{ request.GET.name }}"/>
|
|
||||||
<input class="au-input" type="text" name="department" placeholder="Department" value="{{ request.GET.department }}"/>
|
|
||||||
<button class="btn btn-light" type="submit">
|
<button class="btn btn-light" type="submit">
|
||||||
<i class="fas fa-search"></i> filter
|
<i class="fas fa-search"></i> Filter
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -63,7 +61,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for student in object_list %}
|
{% for student in filter.qs %}
|
||||||
<tr>
|
<tr>
|
||||||
<td> {{ forloop.counter }}.</td>
|
<td> {{ forloop.counter }}.</td>
|
||||||
<td>{{ student.student.username }} </td>
|
<td>{{ student.student.username }} </td>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user