diff --git a/README.md b/README.md
index 25663ffb..dab5a028 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,7 @@ Requirements
1. python-mysqldb
1. django 3.0
1. libldap2-dev
+1. libmysqlclient-dev
```
#### Installation
@@ -34,7 +35,7 @@ chmod +x setup.sh
Installation of Requirements
```bash
-sudo apt install apache2 mysql-server python python3-pip python-mysqldb libldap2-dev
+sudo apt install apache2 mysql-server python python3-pip python-mysqldb libldap2-dev libmysqlclient-dev
sudo python3 -m pip install -r requirements.txt
```
@@ -62,7 +63,7 @@ DATABASES = {
```bash
python3 manage.py makemigrations
python3 manage.py migrate
-python3 manage.py runserver 127.0.0.1:8000
+python3 manage.py runserver 127.0.0.1:8090
```
1. Open "http://127.0.0.1:8090" in your browser.
diff --git a/course/filters.py b/course/filters.py
index eb46e5c3..86f44e99 100644
--- a/course/filters.py
+++ b/course/filters.py
@@ -39,40 +39,87 @@ class Meta:
class LevelFilter(django_filters.FilterSet):
+ institute_id = django_filters.ModelChoiceFilter(
+ field_name="institute",
+ lookup_expr="exact",
+ empty_label="Select Institute",
+ queryset=Institute.objects.all(),
+ )
+
class Meta:
model = Level
fields = {"level_name": ["icontains"]}
class ProgrammeFilter(django_filters.FilterSet):
+ level_id = django_filters.ModelChoiceFilter(
+ field_name="level",
+ lookup_expr="exact",
+ empty_label="Select Level",
+ queryset=Level.objects.all(),
+ )
+
class Meta:
model = Programme
fields = {"programme_code": ["exact"], "programme_name": ["icontains"]}
class DisciplineFilter(django_filters.FilterSet):
+ department_code = django_filters.ModelChoiceFilter(
+ field_name="department",
+ lookup_expr="exact",
+ empty_label="Select Department",
+ queryset=Department.objects.all(),
+ )
+ programme_code = django_filters.ModelChoiceFilter(
+ field_name="programme",
+ lookup_expr="exact",
+ empty_label="Select Programme",
+ queryset=Programme.objects.all(),
+ )
+
class Meta:
model = Discipline
fields = {
"discipline_code": ["exact"],
"discipline_name": ["icontains"],
- "department__department_name": ["icontains"],
}
class CourseFilter(django_filters.FilterSet):
+ discipline_code = django_filters.ModelChoiceFilter(
+ field_name="discipline",
+ lookup_expr="exact",
+ empty_label="Select Discipline",
+ queryset=Discipline.objects.all(),
+ )
+
class Meta:
model = Course
fields = {"course_id": ["exact"], "course_title": ["icontains"]}
class ModuleFilter(django_filters.FilterSet):
+ course_id = django_filters.ModelChoiceFilter(
+ field_name="course",
+ lookup_expr="exact",
+ empty_label="Select Course",
+ queryset=Course.objects.all(),
+ )
+
class Meta:
model = Module
fields = {"module_title": ["icontains"]}
class UnitFilter(django_filters.FilterSet):
+ module_id = django_filters.ModelChoiceFilter(
+ field_name="module",
+ lookup_expr="exact",
+ empty_label="Select Module",
+ queryset=Module.objects.all(),
+ )
+
class Meta:
model = Unit
fields = {"unit_name": ["icontains"]}
diff --git a/course/tables.py b/course/tables.py
index b8edff75..1b8071a4 100644
--- a/course/tables.py
+++ b/course/tables.py
@@ -1,6 +1,7 @@
from django.urls import reverse
from django.utils.safestring import mark_safe
import django_tables2 as tables
+import bootstrap4.templatetags.bootstrap4 as bootstrap
from .models import *
@@ -72,6 +73,7 @@ class InstituteTable(tables.Table):
edit = tables.Column(
verbose_name="Edit Institute",
accessor=tables.A("institute_id"),
+ attrs={"td": {"align": "center"}},
orderable=False,
exclude_from_export=True,
)
@@ -86,22 +88,39 @@ def before_render(self, request):
if self.request.user.is_authenticated == False:
self.columns.hide("edit")
+ def render_institute_name(self, value):
+ institute_id = Institute.objects.get(institute_name=value).institute_id
+ url = (reverse("level") + "?institute_id=%s") % (institute_id,)
+ return mark_safe(
+ bootstrap.bootstrap_button(
+ content=value,
+ href=url,
+ button_class="btn-link",
+ extra_classes="text-body",
+ )
+ )
+
def render_edit(self, value):
url = reverse("edit-institute", args=[value])
- return mark_safe('Edit' % (url,))
+ return mark_safe(
+ bootstrap.bootstrap_button(
+ content="Edit", href=url, button_class="btn-link"
+ )
+ )
class LevelTable(tables.Table):
edit = tables.Column(
verbose_name="Edit Level",
accessor=tables.A("level_id"),
+ attrs={"td": {"align": "center"}},
orderable=False,
exclude_from_export=True,
)
class Meta:
model = Level
- fields = ("level_name", "level_short_name")
+ fields = ("level_name", "level_short_name", "institute")
attrs = {"class": "table-striped table-bordered"}
empty_text = "There is no level matching the search criteria..."
@@ -109,15 +128,32 @@ def before_render(self, request):
if self.request.user.is_authenticated == False:
self.columns.hide("edit")
+ def render_level_name(self, value):
+ level_id = Level.objects.get(level_name=value).level_id
+ url = (reverse("programme") + "?level_id=%s") % (level_id,)
+ return mark_safe(
+ bootstrap.bootstrap_button(
+ content=value,
+ href=url,
+ button_class="btn-link",
+ extra_classes="text-body",
+ )
+ )
+
def render_edit(self, value):
url = reverse("edit-level", args=[value])
- return mark_safe('Edit' % (url,))
+ return mark_safe(
+ bootstrap.bootstrap_button(
+ content="Edit", href=url, button_class="btn-link"
+ )
+ )
class ProgrammeTable(tables.Table):
edit = tables.Column(
verbose_name="Edit Programme",
accessor=tables.A("programme_code"),
+ attrs={"td": {"align": "center"}},
orderable=False,
exclude_from_export=True,
)
@@ -129,6 +165,7 @@ class Meta:
"programme_name",
"programme_short_name",
"programme_fees",
+ "level",
)
attrs = {"class": "table-striped table-bordered"}
empty_text = "There is no programme matching the search criteria..."
@@ -137,15 +174,34 @@ def before_render(self, request):
if self.request.user.is_authenticated == False:
self.columns.hide("edit")
+ def render_programme_name(self, value):
+ programme_code = Programme.objects.get(
+ programme_name=value
+ ).programme_code
+ url = (reverse("discipline") + "?programme_code=%s") % (programme_code,)
+ return mark_safe(
+ bootstrap.bootstrap_button(
+ content=value,
+ href=url,
+ button_class="btn-link",
+ extra_classes="text-body",
+ )
+ )
+
def render_edit(self, value):
url = reverse("edit-programme", args=[value])
- return mark_safe('Edit' % (url,))
+ return mark_safe(
+ bootstrap.bootstrap_button(
+ content="Edit", href=url, button_class="btn-link"
+ )
+ )
class DepartmentTable(tables.Table):
edit = tables.Column(
verbose_name="Edit Department",
accessor=tables.A("department_code"),
+ attrs={"td": {"align": "center"}},
orderable=False,
exclude_from_export=True,
)
@@ -162,13 +218,18 @@ def before_render(self, request):
def render_edit(self, value):
url = reverse("edit-department", args=[value])
- return mark_safe('Edit' % (url,))
+ return mark_safe(
+ bootstrap.bootstrap_button(
+ content="Edit", href=url, button_class="btn-link"
+ )
+ )
class DisciplineTable(tables.Table):
edit = tables.Column(
verbose_name="Edit Discipline",
accessor=tables.A("discipline_code"),
+ attrs={"td": {"align": "center"}},
orderable=False,
exclude_from_export=True,
)
@@ -181,6 +242,7 @@ class Meta:
"discipline_short_name",
"total_credits",
"department",
+ "programme",
)
attrs = {"class": "table-striped table-bordered"}
empty_text = "There is no discipline matching the search criteria..."
@@ -189,15 +251,34 @@ def before_render(self, request):
if self.request.user.is_authenticated == False:
self.columns.hide("edit")
+ def render_discipline_name(self, value):
+ discipline_code = Discipline.objects.get(
+ discipline_name=value
+ ).discipline_code
+ url = (reverse("course") + "?discipline_code=%s") % (discipline_code,)
+ return mark_safe(
+ bootstrap.bootstrap_button(
+ content=value,
+ href=url,
+ button_class="btn-link",
+ extra_classes="text-body",
+ )
+ )
+
def render_edit(self, value):
url = reverse("edit-discipline", args=[value])
- return mark_safe('Edit' % (url,))
+ return mark_safe(
+ bootstrap.bootstrap_button(
+ content="Edit", href=url, button_class="btn-link"
+ )
+ )
class CourseTable(tables.Table):
edit = tables.Column(
verbose_name="Edit Course",
accessor=tables.A("course_id"),
+ attrs={"td": {"align": "center"}},
orderable=False,
exclude_from_export=True,
)
@@ -217,6 +298,7 @@ class Meta:
"practical_contact_hours_per_week",
"course_resources",
"course_test",
+ "discipline",
)
attrs = {"class": "table-striped table-bordered"}
empty_text = "There is no course matching the search criteria..."
@@ -225,15 +307,32 @@ def before_render(self, request):
if self.request.user.is_authenticated == False:
self.columns.hide("edit")
+ def render_course_title(self, value):
+ course_id = Course.objects.get(course_title=value).course_id
+ url = (reverse("module") + "?course_id=%s") % (course_id,)
+ return mark_safe(
+ bootstrap.bootstrap_button(
+ content=value,
+ href=url,
+ button_class="btn-link",
+ extra_classes="text-body",
+ )
+ )
+
def render_edit(self, value):
url = reverse("edit-course", args=[value])
- return mark_safe('Edit' % (url,))
+ return mark_safe(
+ bootstrap.bootstrap_button(
+ content="Edit", href=url, button_class="btn-link"
+ )
+ )
class ModuleTable(tables.Table):
edit = tables.Column(
verbose_name="Edit Module",
accessor=tables.A("module_id"),
+ attrs={"td": {"align": "center"}},
orderable=False,
exclude_from_export=True,
)
@@ -249,6 +348,7 @@ class Meta:
"module_body",
"module_resources",
"module_test",
+ "course",
)
attrs = {"class": "table-striped table-bordered"}
empty_text = "There is no module matching the search criteria..."
@@ -257,15 +357,32 @@ def before_render(self, request):
if self.request.user.is_authenticated == False:
self.columns.hide("edit")
+ def render_module_title(self, value):
+ module_id = Module.objects.get(module_title=value).module_id
+ url = (reverse("unit") + "?module_id=%s") % (module_id,)
+ return mark_safe(
+ bootstrap.bootstrap_button(
+ content=value,
+ href=url,
+ button_class="btn-link",
+ extra_classes="text-body",
+ )
+ )
+
def render_edit(self, value):
url = reverse("edit-module", args=[value])
- return mark_safe('Edit' % (url,))
+ return mark_safe(
+ bootstrap.bootstrap_button(
+ content="Edit", href=url, button_class="btn-link"
+ )
+ )
class UnitTable(tables.Table):
edit = tables.Column(
verbose_name="Edit Unit",
accessor=tables.A("unit_number"),
+ attrs={"td": {"align": "center"}},
orderable=False,
exclude_from_export=True,
)
@@ -281,6 +398,7 @@ class Meta:
"unit_body",
"unit_resources",
"unit_test",
+ "module",
)
attrs = {"class": "table-striped table-bordered"}
empty_text = "There is no unit matching the search criteria..."
@@ -291,4 +409,8 @@ def before_render(self, request):
def render_edit(self, value):
url = reverse("edit-unit", args=[value])
- return mark_safe('Edit' % (url,))
+ return mark_safe(
+ bootstrap.bootstrap_button(
+ content="Edit", href=url, button_class="btn-link"
+ )
+ )
diff --git a/course/urls.py b/course/urls.py
index 94b3388a..0f43c210 100644
--- a/course/urls.py
+++ b/course/urls.py
@@ -3,7 +3,7 @@
from django.contrib.auth.decorators import login_required
urlpatterns = [
- path("", home_page),
+ path("", home_page, name="home"),
path(
"cognitive-level/", CognitiveLevelView.as_view(), name="cognitive-level"
),
diff --git a/requirements.txt b/requirements.txt
index cf4ff8f5..2549be92 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,10 +1,12 @@
black==19.10b0
-Django==3.0
+Django==3.0.1
django-auth-ldap==2.1.0
django-bootstrap4==1.1.1
django-crispy-forms==1.8.1
+django-filter==2.2.0
django-money==1.0
django-tables2==2.2.1
martor==1.4.4
mysqlclient==1.4.6
pre-commit==1.20.0
+python-ldap==3.2.0