Resolve lint warnings
This commit is contained in:
parent
ca47cbf8c7
commit
11154d2fd1
@ -5,13 +5,31 @@ from .models import User, Student, Parent
|
|||||||
|
|
||||||
|
|
||||||
class UserAdmin(admin.ModelAdmin):
|
class UserAdmin(admin.ModelAdmin):
|
||||||
list_display = ['get_full_name', 'username', 'email', 'is_active', 'is_student', 'is_lecturer', 'is_parent', 'is_staff']
|
list_display = [
|
||||||
search_fields = ['username', 'first_name', 'last_name', 'email', 'is_active', 'is_lecturer', 'is_parent', 'is_staff']
|
"get_full_name",
|
||||||
|
"username",
|
||||||
|
"email",
|
||||||
|
"is_active",
|
||||||
|
"is_student",
|
||||||
|
"is_lecturer",
|
||||||
|
"is_parent",
|
||||||
|
"is_staff",
|
||||||
|
]
|
||||||
|
search_fields = [
|
||||||
|
"username",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"email",
|
||||||
|
"is_active",
|
||||||
|
"is_lecturer",
|
||||||
|
"is_parent",
|
||||||
|
"is_staff",
|
||||||
|
]
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
managed = True
|
managed = True
|
||||||
verbose_name = 'User'
|
verbose_name = "User"
|
||||||
verbose_name_plural = 'Users'
|
verbose_name_plural = "Users"
|
||||||
|
|
||||||
|
|
||||||
# class ScoreAdmin(admin.ModelAdmin):
|
# class ScoreAdmin(admin.ModelAdmin):
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from django.contrib.auth.views import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
User = get_user_model()
|
|
||||||
|
|
||||||
|
|
||||||
class UserSerializer(serializers.ModelSerializer):
|
class UserSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = get_user_model()
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
from . import views
|
|
||||||
|
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
from . import views
|
||||||
|
|
||||||
app_name = "accounts-api"
|
app_name = "accounts-api"
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.UserListAPIView.as_view(), name="users-api"),
|
path("", views.UserListAPIView.as_view(), name="users-api"),
|
||||||
]
|
]
|
||||||
@ -1,24 +1,23 @@
|
|||||||
from rest_framework import generics
|
from rest_framework import generics
|
||||||
from django.contrib.auth.views import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
from .serializers import UserSerializer
|
from .serializers import UserSerializer
|
||||||
|
|
||||||
User = get_user_model()
|
|
||||||
|
|
||||||
|
|
||||||
class UserListAPIView(generics.ListAPIView):
|
class UserListAPIView(generics.ListAPIView):
|
||||||
lookup_field = 'id'
|
lookup_field = "id"
|
||||||
serializer_class = UserSerializer
|
serializer_class = UserSerializer
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
qs = User.objects.all()
|
qs = get_user_model().objects.all()
|
||||||
q = self.request.GET.get('q')
|
q = self.request.GET.get("q")
|
||||||
if q is not None:
|
if q is not None:
|
||||||
qs = qs.filter(username__iexact=q)
|
qs = qs.filter(username__iexact=q)
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
class UserDetailView(generics.RetrieveAPIView):
|
class UserDetailView(generics.RetrieveAPIView):
|
||||||
lookup_field = 'id'
|
User = get_user_model()
|
||||||
|
lookup_field = "id"
|
||||||
queryset = User.objects.all()
|
queryset = User.objects.all()
|
||||||
model = User
|
model = User
|
||||||
|
|||||||
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
|
|
||||||
class AccountsConfig(AppConfig):
|
class AccountsConfig(AppConfig):
|
||||||
name = 'accounts'
|
name = "accounts"
|
||||||
|
|||||||
@ -3,7 +3,9 @@ from django.http import Http404
|
|||||||
from django.contrib.auth.decorators import user_passes_test
|
from django.contrib.auth.decorators import user_passes_test
|
||||||
|
|
||||||
|
|
||||||
def student_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=Http404):
|
def student_required(
|
||||||
|
function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=Http404
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Decorator for views that checks that the logged in user is a student,
|
Decorator for views that checks that the logged in user is a student,
|
||||||
redirects to the log-in page if necessary.
|
redirects to the log-in page if necessary.
|
||||||
@ -11,14 +13,16 @@ def student_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, log
|
|||||||
actual_decorator = user_passes_test(
|
actual_decorator = user_passes_test(
|
||||||
lambda u: u.is_active and u.is_student or u.is_superuser,
|
lambda u: u.is_active and u.is_student or u.is_superuser,
|
||||||
login_url=login_url,
|
login_url=login_url,
|
||||||
redirect_field_name=redirect_field_name
|
redirect_field_name=redirect_field_name,
|
||||||
)
|
)
|
||||||
if function:
|
if function:
|
||||||
return actual_decorator(function)
|
return actual_decorator(function)
|
||||||
return actual_decorator
|
return actual_decorator
|
||||||
|
|
||||||
|
|
||||||
def lecturer_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=Http404):
|
def lecturer_required(
|
||||||
|
function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=Http404
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Decorator for views that checks that the logged in user is a teacher,
|
Decorator for views that checks that the logged in user is a teacher,
|
||||||
redirects to the log-in page if necessary.
|
redirects to the log-in page if necessary.
|
||||||
@ -26,14 +30,16 @@ def lecturer_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, lo
|
|||||||
actual_decorator = user_passes_test(
|
actual_decorator = user_passes_test(
|
||||||
lambda u: u.is_active and u.is_lecturer or u.is_superuser,
|
lambda u: u.is_active and u.is_lecturer or u.is_superuser,
|
||||||
login_url=login_url,
|
login_url=login_url,
|
||||||
redirect_field_name=redirect_field_name
|
redirect_field_name=redirect_field_name,
|
||||||
)
|
)
|
||||||
if function:
|
if function:
|
||||||
return actual_decorator(function)
|
return actual_decorator(function)
|
||||||
return actual_decorator
|
return actual_decorator
|
||||||
|
|
||||||
|
|
||||||
def admin_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=Http404):
|
def admin_required(
|
||||||
|
function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=Http404
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Decorator for views that checks that the logged in user is a teacher,
|
Decorator for views that checks that the logged in user is a teacher,
|
||||||
redirects to the log-in page if necessary.
|
redirects to the log-in page if necessary.
|
||||||
@ -41,7 +47,7 @@ def admin_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login
|
|||||||
actual_decorator = user_passes_test(
|
actual_decorator = user_passes_test(
|
||||||
lambda u: u.is_active and u.is_superuser,
|
lambda u: u.is_active and u.is_superuser,
|
||||||
login_url=login_url,
|
login_url=login_url,
|
||||||
redirect_field_name=redirect_field_name
|
redirect_field_name=redirect_field_name,
|
||||||
)
|
)
|
||||||
if function:
|
if function:
|
||||||
return actual_decorator(function)
|
return actual_decorator(function)
|
||||||
|
|||||||
@ -1,82 +1,59 @@
|
|||||||
from django import forms
|
from django import forms
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.contrib.auth.forms import UserCreationForm, UserChangeForm, PasswordChangeForm
|
from django.contrib.auth.forms import (
|
||||||
|
UserCreationForm,
|
||||||
|
UserChangeForm,
|
||||||
|
)
|
||||||
|
|
||||||
# from django.contrib.auth.models import User
|
# from django.contrib.auth.models import User
|
||||||
from django.contrib.auth.forms import PasswordResetForm
|
from django.contrib.auth.forms import PasswordResetForm
|
||||||
|
|
||||||
from course.models import Program
|
from course.models import Program
|
||||||
|
|
||||||
# from .models import User, Student, LEVEL
|
# from .models import User, Student, LEVEL
|
||||||
from .models import *
|
from .models import *
|
||||||
|
|
||||||
|
|
||||||
class StaffAddForm(UserCreationForm):
|
class StaffAddForm(UserCreationForm):
|
||||||
username = forms.CharField(
|
|
||||||
max_length=30, widget=forms.TextInput(attrs={'type': 'text', 'class': 'form-control', }),
|
|
||||||
label="Username", )
|
|
||||||
|
|
||||||
first_name = forms.CharField(
|
|
||||||
max_length=30, widget=forms.TextInput(attrs={'type': 'text', 'class': 'form-control', }),
|
|
||||||
label="First Name", )
|
|
||||||
|
|
||||||
last_name = forms.CharField(
|
|
||||||
max_length=30, widget=forms.TextInput(attrs={'type': 'text', 'class': 'form-control', }),
|
|
||||||
label="Last Name", )
|
|
||||||
|
|
||||||
address = forms.CharField(
|
|
||||||
max_length=30, widget=forms.TextInput(attrs={'type': 'text', 'class': 'form-control', }),
|
|
||||||
label="Address", )
|
|
||||||
|
|
||||||
phone = forms.CharField(
|
|
||||||
max_length=30, widget=forms.TextInput(attrs={'type': 'text', 'class': 'form-control', }),
|
|
||||||
label="Mobile No.", )
|
|
||||||
|
|
||||||
email = forms.CharField(
|
|
||||||
max_length=30, widget=forms.TextInput(attrs={'type': 'text', 'class': 'form-control', }),
|
|
||||||
label="Email", )
|
|
||||||
|
|
||||||
password1 = forms.CharField(
|
|
||||||
max_length=30, widget=forms.TextInput(attrs={'type': 'password', 'class': 'form-control', }),
|
|
||||||
label="Password", )
|
|
||||||
|
|
||||||
password2 = forms.CharField(
|
|
||||||
max_length=30, widget=forms.TextInput(attrs={'type': 'password', 'class': 'form-control', }),
|
|
||||||
label="Password Confirmation", )
|
|
||||||
|
|
||||||
class Meta(UserCreationForm.Meta):
|
|
||||||
model = User
|
|
||||||
|
|
||||||
@transaction.atomic()
|
|
||||||
def save(self, commit=True):
|
|
||||||
user = super().save(commit=False)
|
|
||||||
user.is_lecturer = True
|
|
||||||
user.first_name = self.cleaned_data.get('first_name')
|
|
||||||
user.last_name = self.cleaned_data.get('last_name')
|
|
||||||
user.phone = self.cleaned_data.get('phone')
|
|
||||||
user.address = self.cleaned_data.get('address')
|
|
||||||
user.email = self.cleaned_data.get('email')
|
|
||||||
if commit:
|
|
||||||
user.save()
|
|
||||||
return user
|
|
||||||
|
|
||||||
|
|
||||||
class StudentAddForm(UserCreationForm):
|
|
||||||
username = forms.CharField(
|
username = forms.CharField(
|
||||||
max_length=30,
|
max_length=30,
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
'type': 'text',
|
"type": "text",
|
||||||
'class': 'form-control',
|
"class": "form-control",
|
||||||
'id': 'username_id'
|
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
label="Username",
|
label="Username",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
first_name = forms.CharField(
|
||||||
|
max_length=30,
|
||||||
|
widget=forms.TextInput(
|
||||||
|
attrs={
|
||||||
|
"type": "text",
|
||||||
|
"class": "form-control",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
label="First Name",
|
||||||
|
)
|
||||||
|
|
||||||
|
last_name = forms.CharField(
|
||||||
|
max_length=30,
|
||||||
|
widget=forms.TextInput(
|
||||||
|
attrs={
|
||||||
|
"type": "text",
|
||||||
|
"class": "form-control",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
label="Last Name",
|
||||||
|
)
|
||||||
|
|
||||||
address = forms.CharField(
|
address = forms.CharField(
|
||||||
max_length=30,
|
max_length=30,
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
'type': 'text',
|
"type": "text",
|
||||||
'class': 'form-control',
|
"class": "form-control",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
label="Address",
|
label="Address",
|
||||||
@ -86,8 +63,88 @@ class StudentAddForm(UserCreationForm):
|
|||||||
max_length=30,
|
max_length=30,
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
'type': 'text',
|
"type": "text",
|
||||||
'class': 'form-control',
|
"class": "form-control",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
label="Mobile No.",
|
||||||
|
)
|
||||||
|
|
||||||
|
email = forms.CharField(
|
||||||
|
max_length=30,
|
||||||
|
widget=forms.TextInput(
|
||||||
|
attrs={
|
||||||
|
"type": "text",
|
||||||
|
"class": "form-control",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
label="Email",
|
||||||
|
)
|
||||||
|
|
||||||
|
password1 = forms.CharField(
|
||||||
|
max_length=30,
|
||||||
|
widget=forms.TextInput(
|
||||||
|
attrs={
|
||||||
|
"type": "password",
|
||||||
|
"class": "form-control",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
label="Password",
|
||||||
|
)
|
||||||
|
|
||||||
|
password2 = forms.CharField(
|
||||||
|
max_length=30,
|
||||||
|
widget=forms.TextInput(
|
||||||
|
attrs={
|
||||||
|
"type": "password",
|
||||||
|
"class": "form-control",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
label="Password Confirmation",
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta(UserCreationForm.Meta):
|
||||||
|
model = User
|
||||||
|
|
||||||
|
@transaction.atomic()
|
||||||
|
def save(self, commit=True):
|
||||||
|
user = super().save(commit=False)
|
||||||
|
user.is_lecturer = True
|
||||||
|
user.first_name = self.cleaned_data.get("first_name")
|
||||||
|
user.last_name = self.cleaned_data.get("last_name")
|
||||||
|
user.phone = self.cleaned_data.get("phone")
|
||||||
|
user.address = self.cleaned_data.get("address")
|
||||||
|
user.email = self.cleaned_data.get("email")
|
||||||
|
if commit:
|
||||||
|
user.save()
|
||||||
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
class StudentAddForm(UserCreationForm):
|
||||||
|
username = forms.CharField(
|
||||||
|
max_length=30,
|
||||||
|
widget=forms.TextInput(
|
||||||
|
attrs={"type": "text", "class": "form-control", "id": "username_id"}
|
||||||
|
),
|
||||||
|
label="Username",
|
||||||
|
)
|
||||||
|
address = forms.CharField(
|
||||||
|
max_length=30,
|
||||||
|
widget=forms.TextInput(
|
||||||
|
attrs={
|
||||||
|
"type": "text",
|
||||||
|
"class": "form-control",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
label="Address",
|
||||||
|
)
|
||||||
|
|
||||||
|
phone = forms.CharField(
|
||||||
|
max_length=30,
|
||||||
|
widget=forms.TextInput(
|
||||||
|
attrs={
|
||||||
|
"type": "text",
|
||||||
|
"class": "form-control",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
label="Mobile No.",
|
label="Mobile No.",
|
||||||
@ -97,8 +154,8 @@ class StudentAddForm(UserCreationForm):
|
|||||||
max_length=30,
|
max_length=30,
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
'type': 'text',
|
"type": "text",
|
||||||
'class': 'form-control',
|
"class": "form-control",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
label="First name",
|
label="First name",
|
||||||
@ -108,8 +165,8 @@ class StudentAddForm(UserCreationForm):
|
|||||||
max_length=30,
|
max_length=30,
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
'type': 'text',
|
"type": "text",
|
||||||
'class': 'form-control',
|
"class": "form-control",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
label="Last name",
|
label="Last name",
|
||||||
@ -119,34 +176,50 @@ class StudentAddForm(UserCreationForm):
|
|||||||
widget=forms.Select(
|
widget=forms.Select(
|
||||||
choices=LEVEL,
|
choices=LEVEL,
|
||||||
attrs={
|
attrs={
|
||||||
'class': 'browser-default custom-select form-control',
|
"class": "browser-default custom-select form-control",
|
||||||
}
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
department = forms.ModelChoiceField(
|
department = forms.ModelChoiceField(
|
||||||
queryset=Program.objects.all(),
|
queryset=Program.objects.all(),
|
||||||
widget=forms.Select(attrs={'class': 'browser-default custom-select form-control'}),
|
widget=forms.Select(
|
||||||
|
attrs={"class": "browser-default custom-select form-control"}
|
||||||
|
),
|
||||||
label="Department",
|
label="Department",
|
||||||
)
|
)
|
||||||
|
|
||||||
email = forms.EmailField(
|
email = forms.EmailField(
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
'type': 'email',
|
"type": "email",
|
||||||
'class': 'form-control',
|
"class": "form-control",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
label="Email Address",
|
label="Email Address",
|
||||||
)
|
)
|
||||||
|
|
||||||
password1 = forms.CharField(
|
password1 = forms.CharField(
|
||||||
max_length=30, widget=forms.TextInput(attrs={'type': 'password', 'class': 'form-control', }),
|
max_length=30,
|
||||||
label="Password", )
|
widget=forms.TextInput(
|
||||||
|
attrs={
|
||||||
|
"type": "password",
|
||||||
|
"class": "form-control",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
label="Password",
|
||||||
|
)
|
||||||
|
|
||||||
password2 = forms.CharField(
|
password2 = forms.CharField(
|
||||||
max_length=30, widget=forms.TextInput(attrs={'type': 'password', 'class': 'form-control', }),
|
max_length=30,
|
||||||
label="Password Confirmation", )
|
widget=forms.TextInput(
|
||||||
|
attrs={
|
||||||
|
"type": "password",
|
||||||
|
"class": "form-control",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
label="Password Confirmation",
|
||||||
|
)
|
||||||
|
|
||||||
# def validate_email(self):
|
# def validate_email(self):
|
||||||
# email = self.cleaned_data['email']
|
# email = self.cleaned_data['email']
|
||||||
@ -160,16 +233,16 @@ class StudentAddForm(UserCreationForm):
|
|||||||
def save(self):
|
def save(self):
|
||||||
user = super().save(commit=False)
|
user = super().save(commit=False)
|
||||||
user.is_student = True
|
user.is_student = True
|
||||||
user.first_name = self.cleaned_data.get('first_name')
|
user.first_name = self.cleaned_data.get("first_name")
|
||||||
user.last_name = self.cleaned_data.get('last_name')
|
user.last_name = self.cleaned_data.get("last_name")
|
||||||
user.address = self.cleaned_data.get('address')
|
user.address = self.cleaned_data.get("address")
|
||||||
user.phone = self.cleaned_data.get('phone')
|
user.phone = self.cleaned_data.get("phone")
|
||||||
user.email = self.cleaned_data.get('email')
|
user.email = self.cleaned_data.get("email")
|
||||||
user.save()
|
user.save()
|
||||||
student = Student.objects.create(
|
student = Student.objects.create(
|
||||||
student=user,
|
student=user,
|
||||||
level=self.cleaned_data.get('level'),
|
level=self.cleaned_data.get("level"),
|
||||||
department=self.cleaned_data.get('department')
|
department=self.cleaned_data.get("department"),
|
||||||
)
|
)
|
||||||
student.save()
|
student.save()
|
||||||
return user
|
return user
|
||||||
@ -177,36 +250,66 @@ class StudentAddForm(UserCreationForm):
|
|||||||
|
|
||||||
class ProfileUpdateForm(UserChangeForm):
|
class ProfileUpdateForm(UserChangeForm):
|
||||||
email = forms.EmailField(
|
email = forms.EmailField(
|
||||||
widget=forms.TextInput(attrs={'type': 'email', 'class': 'form-control', }),
|
widget=forms.TextInput(
|
||||||
label="Email Address", )
|
attrs={
|
||||||
|
"type": "email",
|
||||||
|
"class": "form-control",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
label="Email Address",
|
||||||
|
)
|
||||||
|
|
||||||
first_name = forms.CharField(
|
first_name = forms.CharField(
|
||||||
widget=forms.TextInput(attrs={'type': 'text', 'class': 'form-control', }),
|
widget=forms.TextInput(
|
||||||
label="First Name", )
|
attrs={
|
||||||
|
"type": "text",
|
||||||
|
"class": "form-control",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
label="First Name",
|
||||||
|
)
|
||||||
|
|
||||||
last_name = forms.CharField(
|
last_name = forms.CharField(
|
||||||
widget=forms.TextInput(attrs={'type': 'text', 'class': 'form-control', }),
|
widget=forms.TextInput(
|
||||||
label="Last Name", )
|
attrs={
|
||||||
|
"type": "text",
|
||||||
|
"class": "form-control",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
label="Last Name",
|
||||||
|
)
|
||||||
|
|
||||||
phone = forms.CharField(
|
phone = forms.CharField(
|
||||||
widget=forms.TextInput(attrs={'type': 'text', 'class': 'form-control', }),
|
widget=forms.TextInput(
|
||||||
label="Phone No.", )
|
attrs={
|
||||||
|
"type": "text",
|
||||||
|
"class": "form-control",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
label="Phone No.",
|
||||||
|
)
|
||||||
|
|
||||||
address = forms.CharField(
|
address = forms.CharField(
|
||||||
widget=forms.TextInput(attrs={'type': 'text', 'class': 'form-control', }),
|
widget=forms.TextInput(
|
||||||
label="Address / city", )
|
attrs={
|
||||||
|
"type": "text",
|
||||||
|
"class": "form-control",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
label="Address / city",
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = ['email', 'phone', 'address', 'picture', 'first_name', 'last_name']
|
fields = ["email", "phone", "address", "picture", "first_name", "last_name"]
|
||||||
|
|
||||||
|
|
||||||
class EmailValidationOnForgotPassword(PasswordResetForm):
|
class EmailValidationOnForgotPassword(PasswordResetForm):
|
||||||
def clean_email(self):
|
def clean_email(self):
|
||||||
email = self.cleaned_data['email']
|
email = self.cleaned_data["email"]
|
||||||
if not User.objects.filter(email__iexact=email, is_active=True).exists():
|
if not User.objects.filter(email__iexact=email, is_active=True).exists():
|
||||||
msg = "There is no user registered with the specified E-mail address. "
|
msg = "There is no user registered with the specified E-mail address. "
|
||||||
self.add_error('email', msg)
|
self.add_error("email", msg)
|
||||||
return email
|
return email
|
||||||
|
|
||||||
|
|
||||||
@ -215,8 +318,8 @@ class ParentAddForm(UserCreationForm):
|
|||||||
max_length=30,
|
max_length=30,
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
'type': 'text',
|
"type": "text",
|
||||||
'class': 'form-control',
|
"class": "form-control",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
label="Username",
|
label="Username",
|
||||||
@ -225,8 +328,8 @@ class ParentAddForm(UserCreationForm):
|
|||||||
max_length=30,
|
max_length=30,
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
'type': 'text',
|
"type": "text",
|
||||||
'class': 'form-control',
|
"class": "form-control",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
label="Address",
|
label="Address",
|
||||||
@ -236,8 +339,8 @@ class ParentAddForm(UserCreationForm):
|
|||||||
max_length=30,
|
max_length=30,
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
'type': 'text',
|
"type": "text",
|
||||||
'class': 'form-control',
|
"class": "form-control",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
label="Mobile No.",
|
label="Mobile No.",
|
||||||
@ -247,8 +350,8 @@ class ParentAddForm(UserCreationForm):
|
|||||||
max_length=30,
|
max_length=30,
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
'type': 'text',
|
"type": "text",
|
||||||
'class': 'form-control',
|
"class": "form-control",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
label="First name",
|
label="First name",
|
||||||
@ -258,8 +361,8 @@ class ParentAddForm(UserCreationForm):
|
|||||||
max_length=30,
|
max_length=30,
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
'type': 'text',
|
"type": "text",
|
||||||
'class': 'form-control',
|
"class": "form-control",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
label="Last name",
|
label="Last name",
|
||||||
@ -268,8 +371,8 @@ class ParentAddForm(UserCreationForm):
|
|||||||
email = forms.EmailField(
|
email = forms.EmailField(
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
'type': 'email',
|
"type": "email",
|
||||||
'class': 'form-control',
|
"class": "form-control",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
label="Email Address",
|
label="Email Address",
|
||||||
@ -277,24 +380,42 @@ class ParentAddForm(UserCreationForm):
|
|||||||
|
|
||||||
student = forms.ModelChoiceField(
|
student = forms.ModelChoiceField(
|
||||||
queryset=Student.objects.all(),
|
queryset=Student.objects.all(),
|
||||||
widget=forms.Select(attrs={'class': 'browser-default custom-select form-control'}),
|
widget=forms.Select(
|
||||||
|
attrs={"class": "browser-default custom-select form-control"}
|
||||||
|
),
|
||||||
label="Student",
|
label="Student",
|
||||||
)
|
)
|
||||||
|
|
||||||
relation_ship = forms.CharField(
|
relation_ship = forms.CharField(
|
||||||
widget=forms.Select(
|
widget=forms.Select(
|
||||||
choices=RELATION_SHIP,
|
choices=RELATION_SHIP,
|
||||||
attrs={'class': 'browser-default custom-select form-control',}
|
attrs={
|
||||||
|
"class": "browser-default custom-select form-control",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
password1 = forms.CharField(
|
password1 = forms.CharField(
|
||||||
max_length=30, widget=forms.TextInput(attrs={'type': 'password', 'class': 'form-control', }),
|
max_length=30,
|
||||||
label="Password", )
|
widget=forms.TextInput(
|
||||||
|
attrs={
|
||||||
|
"type": "password",
|
||||||
|
"class": "form-control",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
label="Password",
|
||||||
|
)
|
||||||
|
|
||||||
password2 = forms.CharField(
|
password2 = forms.CharField(
|
||||||
max_length=30, widget=forms.TextInput(attrs={'type': 'password', 'class': 'form-control', }),
|
max_length=30,
|
||||||
label="Password Confirmation", )
|
widget=forms.TextInput(
|
||||||
|
attrs={
|
||||||
|
"type": "password",
|
||||||
|
"class": "form-control",
|
||||||
|
}
|
||||||
|
),
|
||||||
|
label="Password Confirmation",
|
||||||
|
)
|
||||||
|
|
||||||
# def validate_email(self):
|
# def validate_email(self):
|
||||||
# email = self.cleaned_data['email']
|
# email = self.cleaned_data['email']
|
||||||
@ -308,16 +429,16 @@ class ParentAddForm(UserCreationForm):
|
|||||||
def save(self):
|
def save(self):
|
||||||
user = super().save(commit=False)
|
user = super().save(commit=False)
|
||||||
user.is_parent = True
|
user.is_parent = True
|
||||||
user.first_name = self.cleaned_data.get('first_name')
|
user.first_name = self.cleaned_data.get("first_name")
|
||||||
user.last_name = self.cleaned_data.get('last_name')
|
user.last_name = self.cleaned_data.get("last_name")
|
||||||
user.address = self.cleaned_data.get('address')
|
user.address = self.cleaned_data.get("address")
|
||||||
user.phone = self.cleaned_data.get('phone')
|
user.phone = self.cleaned_data.get("phone")
|
||||||
user.email = self.cleaned_data.get('email')
|
user.email = self.cleaned_data.get("email")
|
||||||
user.save()
|
user.save()
|
||||||
parent = Parent.objects.create(
|
parent = Parent.objects.create(
|
||||||
user=user,
|
user=user,
|
||||||
student=self.cleaned_data.get('student'),
|
student=self.cleaned_data.get("student"),
|
||||||
relation_ship=self.cleaned_data.get('relation_ship')
|
relation_ship=self.cleaned_data.get("relation_ship"),
|
||||||
)
|
)
|
||||||
parent.save()
|
parent.save()
|
||||||
return user
|
return user
|
||||||
|
|||||||
@ -38,16 +38,20 @@ RELATION_SHIP = (
|
|||||||
(OTHER, "Other"),
|
(OTHER, "Other"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class UserManager(UserManager):
|
class UserManager(UserManager):
|
||||||
def search(self, query=None):
|
def search(self, query=None):
|
||||||
qs = self.get_queryset()
|
qs = self.get_queryset()
|
||||||
if query is not None:
|
if query is not None:
|
||||||
or_lookup = (Q(username__icontains=query) |
|
or_lookup = (
|
||||||
Q(first_name__icontains=query)|
|
Q(username__icontains=query)
|
||||||
Q(last_name__icontains=query)|
|
| Q(first_name__icontains=query)
|
||||||
Q(email__icontains=query)
|
| Q(last_name__icontains=query)
|
||||||
|
| Q(email__icontains=query)
|
||||||
)
|
)
|
||||||
qs = qs.filter(or_lookup).distinct() # distinct() is often necessary with Q lookups
|
qs = qs.filter(
|
||||||
|
or_lookup
|
||||||
|
).distinct() # distinct() is often necessary with Q lookups
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
@ -58,7 +62,9 @@ class User(AbstractUser):
|
|||||||
is_dep_head = models.BooleanField(default=False)
|
is_dep_head = models.BooleanField(default=False)
|
||||||
phone = models.CharField(max_length=60, blank=True, null=True)
|
phone = models.CharField(max_length=60, blank=True, null=True)
|
||||||
address = models.CharField(max_length=60, blank=True, null=True)
|
address = models.CharField(max_length=60, blank=True, null=True)
|
||||||
picture = models.ImageField(upload_to='profile_pictures/%y/%m/%d/', default='default.png', null=True)
|
picture = models.ImageField(
|
||||||
|
upload_to="profile_pictures/%y/%m/%d/", default="default.png", null=True
|
||||||
|
)
|
||||||
email = models.EmailField(blank=True, null=True)
|
email = models.EmailField(blank=True, null=True)
|
||||||
|
|
||||||
username_validator = ASCIIUsernameValidator()
|
username_validator = ASCIIUsernameValidator()
|
||||||
@ -73,7 +79,7 @@ class User(AbstractUser):
|
|||||||
return full_name
|
return full_name
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{} ({})'.format(self.username, self.get_full_name)
|
return "{} ({})".format(self.username, self.get_full_name)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def get_user_role(self):
|
def get_user_role(self):
|
||||||
@ -90,11 +96,11 @@ class User(AbstractUser):
|
|||||||
try:
|
try:
|
||||||
return self.picture.url
|
return self.picture.url
|
||||||
except:
|
except:
|
||||||
no_picture = settings.MEDIA_URL + 'default.png'
|
no_picture = settings.MEDIA_URL + "default.png"
|
||||||
return no_picture
|
return no_picture
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('profile_single', kwargs={'id': self.id})
|
return reverse("profile_single", kwargs={"id": self.id})
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
@ -108,7 +114,7 @@ class User(AbstractUser):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
if self.picture.url != settings.MEDIA_URL + 'default.png':
|
if self.picture.url != settings.MEDIA_URL + "default.png":
|
||||||
self.picture.delete()
|
self.picture.delete()
|
||||||
super().delete(*args, **kwargs)
|
super().delete(*args, **kwargs)
|
||||||
|
|
||||||
@ -117,10 +123,10 @@ class StudentManager(models.Manager):
|
|||||||
def search(self, query=None):
|
def search(self, query=None):
|
||||||
qs = self.get_queryset()
|
qs = self.get_queryset()
|
||||||
if query is not None:
|
if query is not None:
|
||||||
or_lookup = (Q(level__icontains=query) |
|
or_lookup = Q(level__icontains=query) | Q(department__icontains=query)
|
||||||
Q(department__icontains=query)
|
qs = qs.filter(
|
||||||
)
|
or_lookup
|
||||||
qs = qs.filter(or_lookup).distinct() # distinct() is often necessary with Q lookups
|
).distinct() # distinct() is often necessary with Q lookups
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
@ -136,7 +142,7 @@ class Student(models.Model):
|
|||||||
return self.student.get_full_name
|
return self.student.get_full_name
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('profile_single', kwargs={'id': self.id})
|
return reverse("profile_single", kwargs={"id": self.id})
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
self.student.delete()
|
self.student.delete()
|
||||||
@ -148,6 +154,7 @@ class Parent(models.Model):
|
|||||||
Connect student with their parent, parents can
|
Connect student with their parent, parents can
|
||||||
only view their connected students information
|
only view their connected students information
|
||||||
"""
|
"""
|
||||||
|
|
||||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||||
student = models.OneToOneField(Student, null=True, on_delete=models.SET_NULL)
|
student = models.OneToOneField(Student, null=True, on_delete=models.SET_NULL)
|
||||||
first_name = models.CharField(max_length=120)
|
first_name = models.CharField(max_length=120)
|
||||||
|
|||||||
@ -1,57 +1,59 @@
|
|||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from django.contrib.auth.views import (
|
from django.contrib.auth.views import (
|
||||||
PasswordResetView, PasswordResetDoneView, PasswordResetConfirmView,
|
PasswordResetView,
|
||||||
PasswordResetCompleteView, LoginView, LogoutView
|
PasswordResetDoneView,
|
||||||
|
PasswordResetConfirmView,
|
||||||
|
PasswordResetCompleteView,
|
||||||
|
LoginView,
|
||||||
|
LogoutView,
|
||||||
)
|
)
|
||||||
from .views import (
|
from .views import (
|
||||||
profile, profile_single, admin_panel,
|
profile,
|
||||||
profile_update, change_password,
|
profile_single,
|
||||||
LecturerListView, StudentListView,
|
admin_panel,
|
||||||
staff_add_view, edit_staff,
|
profile_update,
|
||||||
delete_staff, student_add_view,
|
change_password,
|
||||||
edit_student, delete_student, ParentAdd, validate_username, register
|
LecturerListView,
|
||||||
|
StudentListView,
|
||||||
|
staff_add_view,
|
||||||
|
edit_staff,
|
||||||
|
delete_staff,
|
||||||
|
student_add_view,
|
||||||
|
edit_student,
|
||||||
|
delete_student,
|
||||||
|
ParentAdd,
|
||||||
|
validate_username,
|
||||||
|
register,
|
||||||
)
|
)
|
||||||
from .forms import EmailValidationOnForgotPassword
|
from .forms import EmailValidationOnForgotPassword
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', include('django.contrib.auth.urls')),
|
path("", include("django.contrib.auth.urls")),
|
||||||
|
path("admin_panel/", admin_panel, name="admin_panel"),
|
||||||
path('admin_panel/', admin_panel, name='admin_panel'),
|
path("profile/", profile, name="profile"),
|
||||||
|
path("profile/<int:id>/detail/", profile_single, name="profile_single"),
|
||||||
path('profile/', profile, name='profile'),
|
path("setting/", profile_update, name="edit_profile"),
|
||||||
path('profile/<int:id>/detail/', profile_single, name='profile_single'),
|
path("change_password/", change_password, name="change_password"),
|
||||||
path('setting/', profile_update, name='edit_profile'),
|
path("lecturers/", LecturerListView.as_view(), name="lecturer_list"),
|
||||||
path('change_password/', change_password, name='change_password'),
|
path("lecturer/add/", staff_add_view, name="add_lecturer"),
|
||||||
|
path("staff/<int:pk>/edit/", edit_staff, name="staff_edit"),
|
||||||
path('lecturers/', LecturerListView.as_view(), name='lecturer_list'),
|
path("lecturers/<int:pk>/delete/", delete_staff, name="lecturer_delete"),
|
||||||
path('lecturer/add/', staff_add_view, name='add_lecturer'),
|
path("students/", StudentListView.as_view(), name="student_list"),
|
||||||
path('staff/<int:pk>/edit/', edit_staff, name='staff_edit'),
|
path("student/add/", student_add_view, name="add_student"),
|
||||||
path('lecturers/<int:pk>/delete/', delete_staff, name='lecturer_delete'),
|
path("student/<int:pk>/edit/", edit_student, name="student_edit"),
|
||||||
|
path("students/<int:pk>/delete/", delete_student, name="student_delete"),
|
||||||
path('students/', StudentListView.as_view(), name='student_list'),
|
path("parents/add/", ParentAdd.as_view(), name="add_parent"),
|
||||||
path('student/add/', student_add_view, name='add_student'),
|
path("ajax/validate-username/", validate_username, name="validate_username"),
|
||||||
path('student/<int:pk>/edit/', edit_student, name='student_edit'),
|
path("register/", register, name="register"),
|
||||||
path('students/<int:pk>/delete/', delete_student, name='student_delete'),
|
|
||||||
|
|
||||||
path('parents/add/', ParentAdd.as_view(), name='add_parent'),
|
|
||||||
|
|
||||||
path('ajax/validate-username/', validate_username, name='validate_username'),
|
|
||||||
|
|
||||||
path('register/', register, name='register'),
|
|
||||||
|
|
||||||
# path('add-student/', StudentAddView.as_view(), name='add_student'),
|
# path('add-student/', StudentAddView.as_view(), name='add_student'),
|
||||||
|
|
||||||
# path('programs/course/delete/<int:pk>/', course_delete, name='delete_course'),
|
# path('programs/course/delete/<int:pk>/', course_delete, name='delete_course'),
|
||||||
|
|
||||||
# Setting urls
|
# Setting urls
|
||||||
# path('profile/<int:pk>/edit/', profileUpdateView, name='edit_profile'),
|
# path('profile/<int:pk>/edit/', profileUpdateView, name='edit_profile'),
|
||||||
# path('profile/<int:pk>/change-password/', changePasswordView, name='change_password'),
|
# path('profile/<int:pk>/change-password/', changePasswordView, name='change_password'),
|
||||||
|
|
||||||
# ################################################################
|
# ################################################################
|
||||||
# path('login/', LoginView.as_view(), name='login'),
|
# path('login/', LoginView.as_view(), name='login'),
|
||||||
# path('logout/', LogoutView.as_view(), name='logout', kwargs={'next_page': '/'}),
|
# path('logout/', LogoutView.as_view(), name='logout', kwargs={'next_page': '/'}),
|
||||||
|
|
||||||
# path('password-reset/', PasswordResetView.as_view(
|
# path('password-reset/', PasswordResetView.as_view(
|
||||||
# form_class=EmailValidationOnForgotPassword,
|
# form_class=EmailValidationOnForgotPassword,
|
||||||
# template_name='registration/password_reset.html'
|
# template_name='registration/password_reset.html'
|
||||||
|
|||||||
@ -7,9 +7,9 @@ from django.utils.translation import gettext_lazy as _
|
|||||||
|
|
||||||
@deconstructible
|
@deconstructible
|
||||||
class ASCIIUsernameValidator(validators.RegexValidator):
|
class ASCIIUsernameValidator(validators.RegexValidator):
|
||||||
regex = r'^[a-zA-Z]+\/(...)\/(....)'
|
regex = r"^[a-zA-Z]+\/(...)\/(....)"
|
||||||
message = _(
|
message = _(
|
||||||
'Enter a valid username. This value may contain only English letters, '
|
"Enter a valid username. This value may contain only English letters, "
|
||||||
'numbers, and @/./+/-/_ characters.'
|
"numbers, and @/./+/-/_ characters."
|
||||||
)
|
)
|
||||||
flags = re.ASCII
|
flags = re.ASCII
|
||||||
|
|||||||
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
|
|
||||||
class AppConfig(AppConfig):
|
class AppConfig(AppConfig):
|
||||||
name = 'app'
|
name = "app"
|
||||||
|
|||||||
42
app/forms.py
42
app/forms.py
@ -8,27 +8,32 @@ from .models import NewsAndEvents, Session, Semester, SEMESTER
|
|||||||
class NewsAndEventsForm(forms.ModelForm):
|
class NewsAndEventsForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = NewsAndEvents
|
model = NewsAndEvents
|
||||||
fields = ('title', 'summary', 'posted_as',)
|
fields = (
|
||||||
|
"title",
|
||||||
|
"summary",
|
||||||
|
"posted_as",
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.fields['title'].widget.attrs.update({'class': 'form-control'})
|
self.fields["title"].widget.attrs.update({"class": "form-control"})
|
||||||
self.fields['summary'].widget.attrs.update({'class': 'form-control'})
|
self.fields["summary"].widget.attrs.update({"class": "form-control"})
|
||||||
self.fields['posted_as'].widget.attrs.update({'class': 'form-control'})
|
self.fields["posted_as"].widget.attrs.update({"class": "form-control"})
|
||||||
|
|
||||||
|
|
||||||
class SessionForm(forms.ModelForm):
|
class SessionForm(forms.ModelForm):
|
||||||
next_session_begins = forms.DateTimeField(
|
next_session_begins = forms.DateTimeField(
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
'type': 'date',
|
"type": "date",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
required=True)
|
required=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Session
|
model = Session
|
||||||
fields = ['session', 'is_current_session', 'next_session_begins']
|
fields = ["session", "is_current_session", "next_session_begins"]
|
||||||
|
|
||||||
|
|
||||||
class SemesterForm(forms.ModelForm):
|
class SemesterForm(forms.ModelForm):
|
||||||
@ -36,17 +41,17 @@ class SemesterForm(forms.ModelForm):
|
|||||||
widget=forms.Select(
|
widget=forms.Select(
|
||||||
choices=SEMESTER,
|
choices=SEMESTER,
|
||||||
attrs={
|
attrs={
|
||||||
'class': 'browser-default custom-select',
|
"class": "browser-default custom-select",
|
||||||
}
|
},
|
||||||
),
|
),
|
||||||
label="semester",
|
label="semester",
|
||||||
)
|
)
|
||||||
is_current_semester = forms.CharField(
|
is_current_semester = forms.CharField(
|
||||||
widget=forms.Select(
|
widget=forms.Select(
|
||||||
choices=((True, 'Yes'), (False, 'No')),
|
choices=((True, "Yes"), (False, "No")),
|
||||||
attrs={
|
attrs={
|
||||||
'class': 'browser-default custom-select',
|
"class": "browser-default custom-select",
|
||||||
}
|
},
|
||||||
),
|
),
|
||||||
label="is current semester ?",
|
label="is current semester ?",
|
||||||
)
|
)
|
||||||
@ -54,21 +59,22 @@ class SemesterForm(forms.ModelForm):
|
|||||||
queryset=Session.objects.all(),
|
queryset=Session.objects.all(),
|
||||||
widget=forms.Select(
|
widget=forms.Select(
|
||||||
attrs={
|
attrs={
|
||||||
'class': 'browser-default custom-select',
|
"class": "browser-default custom-select",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
required=True
|
required=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
next_semester_begins = forms.DateTimeField(
|
next_semester_begins = forms.DateTimeField(
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
'type': 'date',
|
"type": "date",
|
||||||
'class': 'form-control',
|
"class": "form-control",
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
required=True)
|
required=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Semester
|
model = Semester
|
||||||
fields = ['semester', 'is_current_semester', 'session', 'next_semester_begins']
|
fields = ["semester", "is_current_semester", "session", "next_semester_begins"]
|
||||||
|
|||||||
@ -24,11 +24,11 @@ SEMESTER = (
|
|||||||
|
|
||||||
|
|
||||||
class NewsAndEventsQuerySet(models.query.QuerySet):
|
class NewsAndEventsQuerySet(models.query.QuerySet):
|
||||||
|
|
||||||
def search(self, query):
|
def search(self, query):
|
||||||
lookups = (Q(title__icontains=query) |
|
lookups = (
|
||||||
Q(summary__icontains=query) |
|
Q(title__icontains=query)
|
||||||
Q(posted_as__icontains=query)
|
| Q(summary__icontains=query)
|
||||||
|
| Q(posted_as__icontains=query)
|
||||||
)
|
)
|
||||||
return self.filter(lookups).distinct()
|
return self.filter(lookups).distinct()
|
||||||
|
|
||||||
@ -41,7 +41,9 @@ class NewsAndEventsManager(models.Manager):
|
|||||||
return self.get_queryset()
|
return self.get_queryset()
|
||||||
|
|
||||||
def get_by_id(self, id):
|
def get_by_id(self, id):
|
||||||
qs = self.get_queryset().filter(id=id) # NewsAndEvents.objects == self.get_queryset()
|
qs = self.get_queryset().filter(
|
||||||
|
id=id
|
||||||
|
) # NewsAndEvents.objects == self.get_queryset()
|
||||||
if qs.count() == 1:
|
if qs.count() == 1:
|
||||||
return qs.first()
|
return qs.first()
|
||||||
return None
|
return None
|
||||||
@ -75,7 +77,9 @@ class Session(models.Model):
|
|||||||
class Semester(models.Model):
|
class Semester(models.Model):
|
||||||
semester = models.CharField(max_length=10, choices=SEMESTER, blank=True)
|
semester = models.CharField(max_length=10, choices=SEMESTER, blank=True)
|
||||||
is_current_semester = models.BooleanField(default=False, blank=True, null=True)
|
is_current_semester = models.BooleanField(default=False, blank=True, null=True)
|
||||||
session = models.ForeignKey(Session, on_delete=models.CASCADE, blank=True, null=True)
|
session = models.ForeignKey(
|
||||||
|
Session, on_delete=models.CASCADE, blank=True, null=True
|
||||||
|
)
|
||||||
next_semester_begins = models.DateField(null=True, blank=True)
|
next_semester_begins = models.DateField(null=True, blank=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|||||||
46
app/urls.py
46
app/urls.py
@ -1,29 +1,35 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from .views import (
|
from .views import (
|
||||||
home_view, post_add, edit_post, delete_post,
|
home_view,
|
||||||
session_list_view, session_add_view, session_update_view, session_delete_view,
|
post_add,
|
||||||
semester_list_view, semester_add_view, semester_update_view, semester_delete_view,
|
edit_post,
|
||||||
dashboard_view
|
delete_post,
|
||||||
|
session_list_view,
|
||||||
|
session_add_view,
|
||||||
|
session_update_view,
|
||||||
|
session_delete_view,
|
||||||
|
semester_list_view,
|
||||||
|
semester_add_view,
|
||||||
|
semester_update_view,
|
||||||
|
semester_delete_view,
|
||||||
|
dashboard_view,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
# Accounts url
|
# Accounts url
|
||||||
path('', home_view, name='home'),
|
path("", home_view, name="home"),
|
||||||
path('add_item/', post_add, name='add_item'),
|
path("add_item/", post_add, name="add_item"),
|
||||||
path('item/<int:pk>/edit/', edit_post, name='edit_post'),
|
path("item/<int:pk>/edit/", edit_post, name="edit_post"),
|
||||||
path('item/<int:pk>/delete/', delete_post, name='delete_post'),
|
path("item/<int:pk>/delete/", delete_post, name="delete_post"),
|
||||||
|
path("session/", session_list_view, name="session_list"),
|
||||||
path('session/', session_list_view, name="session_list"),
|
path("session/add/", session_add_view, name="add_session"),
|
||||||
path('session/add/', session_add_view, name="add_session"),
|
path("session/<int:pk>/edit/", session_update_view, name="edit_session"),
|
||||||
path('session/<int:pk>/edit/', session_update_view, name="edit_session"),
|
path("session/<int:pk>/delete/", session_delete_view, name="delete_session"),
|
||||||
path('session/<int:pk>/delete/', session_delete_view, name="delete_session"),
|
path("semester/", semester_list_view, name="semester_list"),
|
||||||
|
path("semester/add/", semester_add_view, name="add_semester"),
|
||||||
path('semester/', semester_list_view, name="semester_list"),
|
path("semester/<int:pk>/edit/", semester_update_view, name="edit_semester"),
|
||||||
path('semester/add/', semester_add_view, name="add_semester"),
|
path("semester/<int:pk>/delete/", semester_delete_view, name="delete_semester"),
|
||||||
path('semester/<int:pk>/edit/', semester_update_view, name="edit_semester"),
|
path("dashboard/", dashboard_view, name="dashboard"),
|
||||||
path('semester/<int:pk>/delete/', semester_delete_view, name="delete_semester"),
|
|
||||||
|
|
||||||
path('dashboard/', dashboard_view, name="dashboard"),
|
|
||||||
]
|
]
|
||||||
|
|||||||
174
app/views.py
174
app/views.py
@ -13,54 +13,62 @@ from .models import *
|
|||||||
# ########################################################
|
# ########################################################
|
||||||
@login_required
|
@login_required
|
||||||
def home_view(request):
|
def home_view(request):
|
||||||
items = NewsAndEvents.objects.all().order_by('-updated_date')
|
items = NewsAndEvents.objects.all().order_by("-updated_date")
|
||||||
context = {
|
context = {
|
||||||
'title': "News & Events | DjangoSMS",
|
"title": "News & Events | DjangoSMS",
|
||||||
'items': items,
|
"items": items,
|
||||||
}
|
}
|
||||||
return render(request, 'app/index.html', context)
|
return render(request, "app/index.html", context)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def post_add(request):
|
def post_add(request):
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
form = NewsAndEventsForm(request.POST)
|
form = NewsAndEventsForm(request.POST)
|
||||||
title = request.POST.get('title')
|
title = request.POST.get("title")
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
|
|
||||||
messages.success(request, (title + ' has been uploaded.'))
|
messages.success(request, (title + " has been uploaded."))
|
||||||
return redirect('home')
|
return redirect("home")
|
||||||
else:
|
else:
|
||||||
messages.error(request, 'Please correct the error(s) below.')
|
messages.error(request, "Please correct the error(s) below.")
|
||||||
else:
|
else:
|
||||||
form = NewsAndEventsForm()
|
form = NewsAndEventsForm()
|
||||||
return render(request, 'app/post_add.html', {
|
return render(
|
||||||
'title': 'Add Post | DjangoSMS',
|
request,
|
||||||
'form': form,
|
"app/post_add.html",
|
||||||
})
|
{
|
||||||
|
"title": "Add Post | DjangoSMS",
|
||||||
|
"form": form,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@lecturer_required
|
@lecturer_required
|
||||||
def edit_post(request, pk):
|
def edit_post(request, pk):
|
||||||
instance = get_object_or_404(NewsAndEvents, pk=pk)
|
instance = get_object_or_404(NewsAndEvents, pk=pk)
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
form = NewsAndEventsForm(request.POST, instance=instance)
|
form = NewsAndEventsForm(request.POST, instance=instance)
|
||||||
title = request.POST.get('title')
|
title = request.POST.get("title")
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
|
|
||||||
messages.success(request, (title + ' has been updated.'))
|
messages.success(request, (title + " has been updated."))
|
||||||
return redirect('home')
|
return redirect("home")
|
||||||
else:
|
else:
|
||||||
messages.error(request, 'Please correct the error(s) below.')
|
messages.error(request, "Please correct the error(s) below.")
|
||||||
else:
|
else:
|
||||||
form = NewsAndEventsForm(instance=instance)
|
form = NewsAndEventsForm(instance=instance)
|
||||||
return render(request, 'app/post_add.html', {
|
return render(
|
||||||
'title': 'Edit Post | DjangoSMS',
|
request,
|
||||||
'form': form,
|
"app/post_add.html",
|
||||||
})
|
{
|
||||||
|
"title": "Edit Post | DjangoSMS",
|
||||||
|
"form": form,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -69,8 +77,9 @@ def delete_post(request, pk):
|
|||||||
post = get_object_or_404(NewsAndEvents, pk=pk)
|
post = get_object_or_404(NewsAndEvents, pk=pk)
|
||||||
title = post.title
|
title = post.title
|
||||||
post.delete()
|
post.delete()
|
||||||
messages.success(request, (title + ' has been deleted.'))
|
messages.success(request, (title + " has been deleted."))
|
||||||
return redirect('home')
|
return redirect("home")
|
||||||
|
|
||||||
|
|
||||||
# ########################################################
|
# ########################################################
|
||||||
# Session
|
# Session
|
||||||
@ -79,20 +88,22 @@ def delete_post(request, pk):
|
|||||||
@lecturer_required
|
@lecturer_required
|
||||||
def session_list_view(request):
|
def session_list_view(request):
|
||||||
"""Show list of all sessions"""
|
"""Show list of all sessions"""
|
||||||
sessions = Session.objects.all().order_by('-is_current_session', '-session')
|
sessions = Session.objects.all().order_by("-is_current_session", "-session")
|
||||||
return render(request, 'app/session_list.html', {"sessions": sessions})
|
return render(request, "app/session_list.html", {"sessions": sessions})
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@lecturer_required
|
@lecturer_required
|
||||||
def session_add_view(request):
|
def session_add_view(request):
|
||||||
"""check request method, if POST we add session otherwise show empty form"""
|
"""check request method, if POST we add session otherwise show empty form"""
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
form = SessionForm(request.POST)
|
form = SessionForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
data = form.data.get('is_current_session') # returns string of 'True' if the user selected Yes
|
data = form.data.get(
|
||||||
|
"is_current_session"
|
||||||
|
) # returns string of 'True' if the user selected Yes
|
||||||
print(data)
|
print(data)
|
||||||
if data == 'true':
|
if data == "true":
|
||||||
sessions = Session.objects.all()
|
sessions = Session.objects.all()
|
||||||
if sessions:
|
if sessions:
|
||||||
for session in sessions:
|
for session in sessions:
|
||||||
@ -105,22 +116,22 @@ def session_add_view(request):
|
|||||||
form.save()
|
form.save()
|
||||||
else:
|
else:
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, 'Session added successfully. ')
|
messages.success(request, "Session added successfully. ")
|
||||||
return redirect('session_list')
|
return redirect("session_list")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
form = SessionForm()
|
form = SessionForm()
|
||||||
return render(request, 'app/session_update.html', {'form': form})
|
return render(request, "app/session_update.html", {"form": form})
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@lecturer_required
|
@lecturer_required
|
||||||
def session_update_view(request, pk):
|
def session_update_view(request, pk):
|
||||||
session = Session.objects.get(pk=pk)
|
session = Session.objects.get(pk=pk)
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
form = SessionForm(request.POST, instance=session)
|
form = SessionForm(request.POST, instance=session)
|
||||||
data = form.data.get('is_current_session')
|
data = form.data.get("is_current_session")
|
||||||
if data == 'true':
|
if data == "true":
|
||||||
sessions = Session.objects.all()
|
sessions = Session.objects.all()
|
||||||
if sessions:
|
if sessions:
|
||||||
for session in sessions:
|
for session in sessions:
|
||||||
@ -131,18 +142,18 @@ def session_update_view(request, pk):
|
|||||||
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, 'Session updated successfully. ')
|
messages.success(request, "Session updated successfully. ")
|
||||||
return redirect('session_list')
|
return redirect("session_list")
|
||||||
else:
|
else:
|
||||||
form = SessionForm(request.POST, instance=session)
|
form = SessionForm(request.POST, instance=session)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, 'Session updated successfully. ')
|
messages.success(request, "Session updated successfully. ")
|
||||||
return redirect('session_list')
|
return redirect("session_list")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
form = SessionForm(instance=session)
|
form = SessionForm(instance=session)
|
||||||
return render(request, 'app/session_update.html', {'form': form})
|
return render(request, "app/session_update.html", {"form": form})
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -152,11 +163,13 @@ def session_delete_view(request, pk):
|
|||||||
|
|
||||||
if session.is_current_session:
|
if session.is_current_session:
|
||||||
messages.error(request, "You cannot delete current session")
|
messages.error(request, "You cannot delete current session")
|
||||||
return redirect('session_list')
|
return redirect("session_list")
|
||||||
else:
|
else:
|
||||||
session.delete()
|
session.delete()
|
||||||
messages.success(request, "Session successfully deleted")
|
messages.success(request, "Session successfully deleted")
|
||||||
return redirect('session_list')
|
return redirect("session_list")
|
||||||
|
|
||||||
|
|
||||||
# ########################################################
|
# ########################################################
|
||||||
|
|
||||||
|
|
||||||
@ -166,86 +179,106 @@ def session_delete_view(request, pk):
|
|||||||
@login_required
|
@login_required
|
||||||
@lecturer_required
|
@lecturer_required
|
||||||
def semester_list_view(request):
|
def semester_list_view(request):
|
||||||
semesters = Semester.objects.all().order_by('-is_current_semester', '-semester')
|
semesters = Semester.objects.all().order_by("-is_current_semester", "-semester")
|
||||||
return render(request, 'app/semester_list.html', {"semesters": semesters, })
|
return render(
|
||||||
|
request,
|
||||||
|
"app/semester_list.html",
|
||||||
|
{
|
||||||
|
"semesters": semesters,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@lecturer_required
|
@lecturer_required
|
||||||
def semester_add_view(request):
|
def semester_add_view(request):
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
form = SemesterForm(request.POST)
|
form = SemesterForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
data = form.data.get('is_current_semester') # returns string of 'True' if the user selected Yes
|
data = form.data.get(
|
||||||
if data == 'True':
|
"is_current_semester"
|
||||||
semester = form.data.get('semester')
|
) # returns string of 'True' if the user selected Yes
|
||||||
ss = form.data.get('session')
|
if data == "True":
|
||||||
|
semester = form.data.get("semester")
|
||||||
|
ss = form.data.get("session")
|
||||||
session = Session.objects.get(pk=ss)
|
session = Session.objects.get(pk=ss)
|
||||||
try:
|
try:
|
||||||
if Semester.objects.get(semester=semester, session=ss):
|
if Semester.objects.get(semester=semester, session=ss):
|
||||||
messages.error(request, semester + " semester in " + session.session + " session already exist")
|
messages.error(
|
||||||
return redirect('add_semester')
|
request,
|
||||||
|
semester
|
||||||
|
+ " semester in "
|
||||||
|
+ session.session
|
||||||
|
+ " session already exist",
|
||||||
|
)
|
||||||
|
return redirect("add_semester")
|
||||||
except:
|
except:
|
||||||
semesters = Semester.objects.all()
|
semesters = Semester.objects.all()
|
||||||
sessions = Session.objects.all()
|
sessions = Session.objects.all()
|
||||||
if semesters:
|
if semesters:
|
||||||
for semester in semesters:
|
for semester in semesters:
|
||||||
if semester.is_current_semester == True:
|
if semester.is_current_semester == True:
|
||||||
unset_semester = Semester.objects.get(is_current_semester=True)
|
unset_semester = Semester.objects.get(
|
||||||
|
is_current_semester=True
|
||||||
|
)
|
||||||
unset_semester.is_current_semester = False
|
unset_semester.is_current_semester = False
|
||||||
unset_semester.save()
|
unset_semester.save()
|
||||||
for session in sessions:
|
for session in sessions:
|
||||||
if session.is_current_session == True:
|
if session.is_current_session == True:
|
||||||
unset_session = Session.objects.get(is_current_session=True)
|
unset_session = Session.objects.get(
|
||||||
|
is_current_session=True
|
||||||
|
)
|
||||||
unset_session.is_current_session = False
|
unset_session.is_current_session = False
|
||||||
unset_session.save()
|
unset_session.save()
|
||||||
|
|
||||||
new_session = request.POST.get('session')
|
new_session = request.POST.get("session")
|
||||||
set_session = Session.objects.get(pk=new_session)
|
set_session = Session.objects.get(pk=new_session)
|
||||||
set_session.is_current_session = True
|
set_session.is_current_session = True
|
||||||
set_session.save()
|
set_session.save()
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, 'Semester added successfully.')
|
messages.success(request, "Semester added successfully.")
|
||||||
return redirect('semester_list')
|
return redirect("semester_list")
|
||||||
|
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, 'Semester added successfully. ')
|
messages.success(request, "Semester added successfully. ")
|
||||||
return redirect('semester_list')
|
return redirect("semester_list")
|
||||||
else:
|
else:
|
||||||
form = SemesterForm()
|
form = SemesterForm()
|
||||||
return render(request, 'app/semester_update.html', {'form': form})
|
return render(request, "app/semester_update.html", {"form": form})
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@lecturer_required
|
@lecturer_required
|
||||||
def semester_update_view(request, pk):
|
def semester_update_view(request, pk):
|
||||||
semester = Semester.objects.get(pk=pk)
|
semester = Semester.objects.get(pk=pk)
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
if request.POST.get('is_current_semester') == 'True': # returns string of 'True' if the user selected yes for 'is current semester'
|
if (
|
||||||
|
request.POST.get("is_current_semester") == "True"
|
||||||
|
): # returns string of 'True' if the user selected yes for 'is current semester'
|
||||||
unset_semester = Semester.objects.get(is_current_semester=True)
|
unset_semester = Semester.objects.get(is_current_semester=True)
|
||||||
unset_semester.is_current_semester = False
|
unset_semester.is_current_semester = False
|
||||||
unset_semester.save()
|
unset_semester.save()
|
||||||
unset_session = Session.objects.get(is_current_session=True)
|
unset_session = Session.objects.get(is_current_session=True)
|
||||||
unset_session.is_current_session = False
|
unset_session.is_current_session = False
|
||||||
unset_session.save()
|
unset_session.save()
|
||||||
new_session = request.POST.get('session')
|
new_session = request.POST.get("session")
|
||||||
form = SemesterForm(request.POST, instance=semester)
|
form = SemesterForm(request.POST, instance=semester)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
set_session = Session.objects.get(pk=new_session)
|
set_session = Session.objects.get(pk=new_session)
|
||||||
set_session.is_current_session = True
|
set_session.is_current_session = True
|
||||||
set_session.save()
|
set_session.save()
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, 'Semester updated successfully !')
|
messages.success(request, "Semester updated successfully !")
|
||||||
return redirect('semester_list')
|
return redirect("semester_list")
|
||||||
else:
|
else:
|
||||||
form = SemesterForm(request.POST, instance=semester)
|
form = SemesterForm(request.POST, instance=semester)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
return redirect('semester_list')
|
return redirect("semester_list")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
form = SemesterForm(instance=semester)
|
form = SemesterForm(instance=semester)
|
||||||
return render(request, 'app/semester_update.html', {'form': form})
|
return render(request, "app/semester_update.html", {"form": form})
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -254,11 +287,13 @@ def semester_delete_view(request, pk):
|
|||||||
semester = get_object_or_404(Semester, pk=pk)
|
semester = get_object_or_404(Semester, pk=pk)
|
||||||
if semester.is_current_semester:
|
if semester.is_current_semester:
|
||||||
messages.error(request, "You cannot delete current semester")
|
messages.error(request, "You cannot delete current semester")
|
||||||
return redirect('semester_list')
|
return redirect("semester_list")
|
||||||
else:
|
else:
|
||||||
semester.delete()
|
semester.delete()
|
||||||
messages.success(request, "Semester successfully deleted")
|
messages.success(request, "Semester successfully deleted")
|
||||||
return redirect('semester_list')
|
return redirect("semester_list")
|
||||||
|
|
||||||
|
|
||||||
# ########################################################
|
# ########################################################
|
||||||
|
|
||||||
|
|
||||||
@ -284,7 +319,8 @@ def semester_delete_view(request, pk):
|
|||||||
|
|
||||||
# return response
|
# return response
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@admin_required
|
@admin_required
|
||||||
def dashboard_view(request):
|
def dashboard_view(request):
|
||||||
return render(request, 'app/dashboard.html')
|
return render(request, "app/dashboard.html")
|
||||||
|
|||||||
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
|
|
||||||
class CourseConfig(AppConfig):
|
class CourseConfig(AppConfig):
|
||||||
name = 'course'
|
name = "course"
|
||||||
|
|||||||
@ -8,98 +8,109 @@ from .models import Program, Course, CourseAllocation, Upload, UploadVideo
|
|||||||
|
|
||||||
# User = settings.AUTH_USER_MODEL
|
# User = settings.AUTH_USER_MODEL
|
||||||
|
|
||||||
|
|
||||||
class ProgramForm(forms.ModelForm):
|
class ProgramForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Program
|
model = Program
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.fields['title'].widget.attrs.update({'class': 'form-control'})
|
self.fields["title"].widget.attrs.update({"class": "form-control"})
|
||||||
self.fields['summary'].widget.attrs.update({'class': 'form-control'})
|
self.fields["summary"].widget.attrs.update({"class": "form-control"})
|
||||||
|
|
||||||
|
|
||||||
class CourseAddForm(forms.ModelForm):
|
class CourseAddForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Course
|
model = Course
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.fields['title'].widget.attrs.update({'class': 'form-control'})
|
self.fields["title"].widget.attrs.update({"class": "form-control"})
|
||||||
self.fields['code'].widget.attrs.update({'class': 'form-control'})
|
self.fields["code"].widget.attrs.update({"class": "form-control"})
|
||||||
# self.fields['courseUnit'].widget.attrs.update({'class': 'form-control'})
|
# self.fields['courseUnit'].widget.attrs.update({'class': 'form-control'})
|
||||||
self.fields['credit'].widget.attrs.update({'class': 'form-control'})
|
self.fields["credit"].widget.attrs.update({"class": "form-control"})
|
||||||
self.fields['summary'].widget.attrs.update({'class': 'form-control'})
|
self.fields["summary"].widget.attrs.update({"class": "form-control"})
|
||||||
self.fields['program'].widget.attrs.update({'class': 'form-control'})
|
self.fields["program"].widget.attrs.update({"class": "form-control"})
|
||||||
self.fields['level'].widget.attrs.update({'class': 'form-control'})
|
self.fields["level"].widget.attrs.update({"class": "form-control"})
|
||||||
self.fields['year'].widget.attrs.update({'class': 'form-control'})
|
self.fields["year"].widget.attrs.update({"class": "form-control"})
|
||||||
self.fields['semester'].widget.attrs.update({'class': 'form-control'})
|
self.fields["semester"].widget.attrs.update({"class": "form-control"})
|
||||||
|
|
||||||
|
|
||||||
class CourseAllocationForm(forms.ModelForm):
|
class CourseAllocationForm(forms.ModelForm):
|
||||||
courses = forms.ModelMultipleChoiceField(
|
courses = forms.ModelMultipleChoiceField(
|
||||||
queryset=Course.objects.all().order_by('level'),
|
queryset=Course.objects.all().order_by("level"),
|
||||||
widget=forms.CheckboxSelectMultiple(attrs={'class': 'browser-default checkbox'}),
|
widget=forms.CheckboxSelectMultiple(
|
||||||
required=True
|
attrs={"class": "browser-default checkbox"}
|
||||||
|
),
|
||||||
|
required=True,
|
||||||
)
|
)
|
||||||
lecturer = forms.ModelChoiceField(
|
lecturer = forms.ModelChoiceField(
|
||||||
queryset=User.objects.filter(is_lecturer=True),
|
queryset=User.objects.filter(is_lecturer=True),
|
||||||
widget=forms.Select(attrs={'class': 'browser-default custom-select'}),
|
widget=forms.Select(attrs={"class": "browser-default custom-select"}),
|
||||||
label="lecturer",
|
label="lecturer",
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CourseAllocation
|
model = CourseAllocation
|
||||||
fields = ['lecturer', 'courses']
|
fields = ["lecturer", "courses"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
user = kwargs.pop('user')
|
user = kwargs.pop("user")
|
||||||
super(CourseAllocationForm, self).__init__(*args, **kwargs)
|
super(CourseAllocationForm, self).__init__(*args, **kwargs)
|
||||||
self.fields['lecturer'].queryset = User.objects.filter(is_lecturer=True)
|
self.fields["lecturer"].queryset = User.objects.filter(is_lecturer=True)
|
||||||
|
|
||||||
|
|
||||||
class EditCourseAllocationForm(forms.ModelForm):
|
class EditCourseAllocationForm(forms.ModelForm):
|
||||||
courses = forms.ModelMultipleChoiceField(
|
courses = forms.ModelMultipleChoiceField(
|
||||||
queryset=Course.objects.all().order_by('level'),
|
queryset=Course.objects.all().order_by("level"),
|
||||||
widget=forms.CheckboxSelectMultiple,
|
widget=forms.CheckboxSelectMultiple,
|
||||||
required=True
|
required=True,
|
||||||
)
|
)
|
||||||
lecturer = forms.ModelChoiceField(
|
lecturer = forms.ModelChoiceField(
|
||||||
queryset=User.objects.filter(is_lecturer=True),
|
queryset=User.objects.filter(is_lecturer=True),
|
||||||
widget=forms.Select(attrs={'class': 'browser-default custom-select'}),
|
widget=forms.Select(attrs={"class": "browser-default custom-select"}),
|
||||||
label="lecturer",
|
label="lecturer",
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CourseAllocation
|
model = CourseAllocation
|
||||||
fields = ['lecturer', 'courses']
|
fields = ["lecturer", "courses"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
# user = kwargs.pop('user')
|
# user = kwargs.pop('user')
|
||||||
super(EditCourseAllocationForm, self).__init__(*args, **kwargs)
|
super(EditCourseAllocationForm, self).__init__(*args, **kwargs)
|
||||||
self.fields['lecturer'].queryset = User.objects.filter(is_lecturer=True)
|
self.fields["lecturer"].queryset = User.objects.filter(is_lecturer=True)
|
||||||
|
|
||||||
|
|
||||||
# Upload files to specific course
|
# Upload files to specific course
|
||||||
class UploadFormFile(forms.ModelForm):
|
class UploadFormFile(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Upload
|
model = Upload
|
||||||
fields = ('title', 'file', 'course',)
|
fields = (
|
||||||
|
"title",
|
||||||
|
"file",
|
||||||
|
"course",
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.fields['title'].widget.attrs.update({'class': 'form-control'})
|
self.fields["title"].widget.attrs.update({"class": "form-control"})
|
||||||
self.fields['file'].widget.attrs.update({'class': 'form-control'})
|
self.fields["file"].widget.attrs.update({"class": "form-control"})
|
||||||
|
|
||||||
|
|
||||||
# Upload video to specific course
|
# Upload video to specific course
|
||||||
class UploadFormVideo(forms.ModelForm):
|
class UploadFormVideo(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = UploadVideo
|
model = UploadVideo
|
||||||
fields = ('title', 'video', 'course',)
|
fields = (
|
||||||
|
"title",
|
||||||
|
"video",
|
||||||
|
"course",
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.fields['title'].widget.attrs.update({'class': 'form-control'})
|
self.fields["title"].widget.attrs.update({"class": "form-control"})
|
||||||
self.fields['video'].widget.attrs.update({'class': 'form-control'})
|
self.fields["video"].widget.attrs.update({"class": "form-control"})
|
||||||
|
|||||||
106
course/models.py
106
course/models.py
@ -10,12 +10,12 @@ from .utils import *
|
|||||||
|
|
||||||
|
|
||||||
YEARS = (
|
YEARS = (
|
||||||
(1, '1'),
|
(1, "1"),
|
||||||
(2, '2'),
|
(2, "2"),
|
||||||
(3, '3'),
|
(3, "3"),
|
||||||
(4, '4'),
|
(4, "4"),
|
||||||
(4, '5'),
|
(4, "5"),
|
||||||
(4, '6'),
|
(4, "6"),
|
||||||
)
|
)
|
||||||
|
|
||||||
# LEVEL_COURSE = "Level course"
|
# LEVEL_COURSE = "Level course"
|
||||||
@ -43,10 +43,10 @@ class ProgramManager(models.Manager):
|
|||||||
def search(self, query=None):
|
def search(self, query=None):
|
||||||
qs = self.get_queryset()
|
qs = self.get_queryset()
|
||||||
if query is not None:
|
if query is not None:
|
||||||
or_lookup = (Q(title__icontains=query) |
|
or_lookup = Q(title__icontains=query) | Q(summary__icontains=query)
|
||||||
Q(summary__icontains=query)
|
qs = qs.filter(
|
||||||
)
|
or_lookup
|
||||||
qs = qs.filter(or_lookup).distinct() # distinct() is often necessary with Q lookups
|
).distinct() # distinct() is often necessary with Q lookups
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
@ -60,19 +60,22 @@ class Program(models.Model):
|
|||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('program_detail', kwargs={'pk': self.pk})
|
return reverse("program_detail", kwargs={"pk": self.pk})
|
||||||
|
|
||||||
|
|
||||||
class CourseManager(models.Manager):
|
class CourseManager(models.Manager):
|
||||||
def search(self, query=None):
|
def search(self, query=None):
|
||||||
qs = self.get_queryset()
|
qs = self.get_queryset()
|
||||||
if query is not None:
|
if query is not None:
|
||||||
or_lookup = (Q(title__icontains=query) |
|
or_lookup = (
|
||||||
Q(summary__icontains=query)|
|
Q(title__icontains=query)
|
||||||
Q(code__icontains=query)|
|
| Q(summary__icontains=query)
|
||||||
Q(slug__icontains=query)
|
| Q(code__icontains=query)
|
||||||
|
| Q(slug__icontains=query)
|
||||||
)
|
)
|
||||||
qs = qs.filter(or_lookup).distinct() # distinct() is often necessary with Q lookups
|
qs = qs.filter(
|
||||||
|
or_lookup
|
||||||
|
).distinct() # distinct() is often necessary with Q lookups
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
@ -94,11 +97,12 @@ class Course(models.Model):
|
|||||||
return "{0} ({1})".format(self.title, self.code)
|
return "{0} ({1})".format(self.title, self.code)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('course_detail', kwargs={'slug': self.slug})
|
return reverse("course_detail", kwargs={"slug": self.slug})
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_current_semester(self):
|
def is_current_semester(self):
|
||||||
from app.models import Semester
|
from app.models import Semester
|
||||||
|
|
||||||
current_semester = Semester.objects.get(is_current_semester=True)
|
current_semester = Semester.objects.get(is_current_semester=True)
|
||||||
|
|
||||||
if self.semester == current_semester.semester:
|
if self.semester == current_semester.semester:
|
||||||
@ -111,25 +115,50 @@ def course_pre_save_receiver(sender, instance, *args, **kwargs):
|
|||||||
if not instance.slug:
|
if not instance.slug:
|
||||||
instance.slug = unique_slug_generator(instance)
|
instance.slug = unique_slug_generator(instance)
|
||||||
|
|
||||||
|
|
||||||
pre_save.connect(course_pre_save_receiver, sender=Course)
|
pre_save.connect(course_pre_save_receiver, sender=Course)
|
||||||
|
|
||||||
|
|
||||||
class CourseAllocation(models.Model):
|
class CourseAllocation(models.Model):
|
||||||
lecturer = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='allocated_lecturer')
|
lecturer = models.ForeignKey(
|
||||||
courses = models.ManyToManyField(Course, related_name='allocated_course')
|
settings.AUTH_USER_MODEL,
|
||||||
session = models.ForeignKey("app.Session", on_delete=models.CASCADE, blank=True, null=True)
|
on_delete=models.CASCADE,
|
||||||
|
related_name="allocated_lecturer",
|
||||||
|
)
|
||||||
|
courses = models.ManyToManyField(Course, related_name="allocated_course")
|
||||||
|
session = models.ForeignKey(
|
||||||
|
"app.Session", on_delete=models.CASCADE, blank=True, null=True
|
||||||
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.lecturer.get_full_name
|
return self.lecturer.get_full_name
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('edit_allocated_course', kwargs={'pk': self.pk})
|
return reverse("edit_allocated_course", kwargs={"pk": self.pk})
|
||||||
|
|
||||||
|
|
||||||
class Upload(models.Model):
|
class Upload(models.Model):
|
||||||
title = models.CharField(max_length=100)
|
title = models.CharField(max_length=100)
|
||||||
course = models.ForeignKey(Course, on_delete=models.CASCADE)
|
course = models.ForeignKey(Course, on_delete=models.CASCADE)
|
||||||
file = models.FileField(upload_to='course_files/', validators=[FileExtensionValidator(['pdf', 'docx', 'doc', 'xls', 'xlsx', 'ppt', 'pptx', 'zip', 'rar', '7zip'])])
|
file = models.FileField(
|
||||||
|
upload_to="course_files/",
|
||||||
|
validators=[
|
||||||
|
FileExtensionValidator(
|
||||||
|
[
|
||||||
|
"pdf",
|
||||||
|
"docx",
|
||||||
|
"doc",
|
||||||
|
"xls",
|
||||||
|
"xlsx",
|
||||||
|
"ppt",
|
||||||
|
"pptx",
|
||||||
|
"zip",
|
||||||
|
"rar",
|
||||||
|
"7zip",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
updated_date = models.DateTimeField(auto_now=True, auto_now_add=False, null=True)
|
updated_date = models.DateTimeField(auto_now=True, auto_now_add=False, null=True)
|
||||||
upload_time = models.DateTimeField(auto_now=False, auto_now_add=True, null=True)
|
upload_time = models.DateTimeField(auto_now=False, auto_now_add=True, null=True)
|
||||||
|
|
||||||
@ -140,16 +169,16 @@ class Upload(models.Model):
|
|||||||
ext = str(self.file).split(".")
|
ext = str(self.file).split(".")
|
||||||
ext = ext[len(ext) - 1]
|
ext = ext[len(ext) - 1]
|
||||||
|
|
||||||
if ext == 'doc' or ext == 'docx':
|
if ext == "doc" or ext == "docx":
|
||||||
return 'word'
|
return "word"
|
||||||
elif ext == 'pdf':
|
elif ext == "pdf":
|
||||||
return 'pdf'
|
return "pdf"
|
||||||
elif ext == 'xls' or ext == 'xlsx':
|
elif ext == "xls" or ext == "xlsx":
|
||||||
return 'excel'
|
return "excel"
|
||||||
elif ext == 'ppt' or ext == 'pptx':
|
elif ext == "ppt" or ext == "pptx":
|
||||||
return 'powerpoint'
|
return "powerpoint"
|
||||||
elif ext == 'zip' or ext == 'rar' or ext == '7zip':
|
elif ext == "zip" or ext == "rar" or ext == "7zip":
|
||||||
return 'archive'
|
return "archive"
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
self.file.delete()
|
self.file.delete()
|
||||||
@ -160,7 +189,12 @@ class UploadVideo(models.Model):
|
|||||||
title = models.CharField(max_length=100)
|
title = models.CharField(max_length=100)
|
||||||
slug = models.SlugField(blank=True, unique=True)
|
slug = models.SlugField(blank=True, unique=True)
|
||||||
course = models.ForeignKey(Course, on_delete=models.CASCADE)
|
course = models.ForeignKey(Course, on_delete=models.CASCADE)
|
||||||
video = models.FileField(upload_to='course_videos/', validators=[FileExtensionValidator(['mp4', 'mkv', 'wmv', '3gp', 'f4v', 'avi', 'mp3'])])
|
video = models.FileField(
|
||||||
|
upload_to="course_videos/",
|
||||||
|
validators=[
|
||||||
|
FileExtensionValidator(["mp4", "mkv", "wmv", "3gp", "f4v", "avi", "mp3"])
|
||||||
|
],
|
||||||
|
)
|
||||||
summary = models.TextField(null=True, blank=True)
|
summary = models.TextField(null=True, blank=True)
|
||||||
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True, null=True)
|
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True, null=True)
|
||||||
|
|
||||||
@ -168,7 +202,9 @@ class UploadVideo(models.Model):
|
|||||||
return str(self.title)
|
return str(self.title)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('video_single', kwargs={'slug': self.course.slug, 'video_slug': self.slug})
|
return reverse(
|
||||||
|
"video_single", kwargs={"slug": self.course.slug, "video_slug": self.slug}
|
||||||
|
)
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
self.video.delete()
|
self.video.delete()
|
||||||
@ -179,11 +215,13 @@ def video_pre_save_receiver(sender, instance, *args, **kwargs):
|
|||||||
if not instance.slug:
|
if not instance.slug:
|
||||||
instance.slug = unique_slug_generator(instance)
|
instance.slug = unique_slug_generator(instance)
|
||||||
|
|
||||||
|
|
||||||
pre_save.connect(video_pre_save_receiver, sender=UploadVideo)
|
pre_save.connect(video_pre_save_receiver, sender=UploadVideo)
|
||||||
|
|
||||||
|
|
||||||
class CourseOffer(models.Model):
|
class CourseOffer(models.Model):
|
||||||
"""NOTE: Only department head can offer semester courses"""
|
"""NOTE: Only department head can offer semester courses"""
|
||||||
|
|
||||||
dep_head = models.ForeignKey("accounts.DepartmentHead", on_delete=models.CASCADE)
|
dep_head = models.ForeignKey("accounts.DepartmentHead", on_delete=models.CASCADE)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|||||||
@ -4,38 +4,66 @@ from .views import *
|
|||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
# Program urls
|
# Program urls
|
||||||
path('', program_view, name='programs'),
|
path("", program_view, name="programs"),
|
||||||
path('<int:pk>/detail/', program_detail, name='program_detail'),
|
path("<int:pk>/detail/", program_detail, name="program_detail"),
|
||||||
path('add/', program_add, name='add_program'),
|
path("add/", program_add, name="add_program"),
|
||||||
path('<int:pk>/edit/', program_edit, name='edit_program'),
|
path("<int:pk>/edit/", program_edit, name="edit_program"),
|
||||||
path('<int:pk>/delete/', program_delete, name='program_delete'),
|
path("<int:pk>/delete/", program_delete, name="program_delete"),
|
||||||
|
|
||||||
# Course urls
|
# Course urls
|
||||||
path('course/<slug>/detail/', course_single, name='course_detail'),
|
path("course/<slug>/detail/", course_single, name="course_detail"),
|
||||||
path('<int:pk>/course/add/', course_add, name='course_add'),
|
path("<int:pk>/course/add/", course_add, name="course_add"),
|
||||||
path('course/<slug>/edit/', course_edit, name='edit_course'),
|
path("course/<slug>/edit/", course_edit, name="edit_course"),
|
||||||
path('course/delete/<slug>/', course_delete, name='delete_course'),
|
path("course/delete/<slug>/", course_delete, name="delete_course"),
|
||||||
|
|
||||||
# CourseAllocation urls
|
# CourseAllocation urls
|
||||||
path('course/assign/', CourseAllocationFormView.as_view(), name='course_allocation'),
|
path(
|
||||||
path('course/allocated/', course_allocation_view, name='course_allocation_view'),
|
"course/assign/", CourseAllocationFormView.as_view(), name="course_allocation"
|
||||||
path('allocated_course/<int:pk>/edit/', edit_allocated_course, name='edit_allocated_course'),
|
),
|
||||||
path('course/<int:pk>/deallocate/', deallocate_course, name='course_deallocate'),
|
path("course/allocated/", course_allocation_view, name="course_allocation_view"),
|
||||||
|
path(
|
||||||
|
"allocated_course/<int:pk>/edit/",
|
||||||
|
edit_allocated_course,
|
||||||
|
name="edit_allocated_course",
|
||||||
|
),
|
||||||
|
path("course/<int:pk>/deallocate/", deallocate_course, name="course_deallocate"),
|
||||||
# File uploads urls
|
# File uploads urls
|
||||||
path('course/<slug>/documentations/upload/', handle_file_upload, name='upload_file_view'),
|
path(
|
||||||
path('course/<slug>/documentations/<int:file_id>/edit/', handle_file_edit, name='upload_file_edit'),
|
"course/<slug>/documentations/upload/",
|
||||||
path('course/<slug>/documentations/<int:file_id>/delete/', handle_file_delete, name='upload_file_delete'),
|
handle_file_upload,
|
||||||
|
name="upload_file_view",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"course/<slug>/documentations/<int:file_id>/edit/",
|
||||||
|
handle_file_edit,
|
||||||
|
name="upload_file_edit",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"course/<slug>/documentations/<int:file_id>/delete/",
|
||||||
|
handle_file_delete,
|
||||||
|
name="upload_file_delete",
|
||||||
|
),
|
||||||
# Video uploads urls
|
# Video uploads urls
|
||||||
path('course/<slug>/video_tutorials/upload/', handle_video_upload, name='upload_video'),
|
path(
|
||||||
path('course/<slug>/video_tutorials/<video_slug>/detail/', handle_video_single, name='video_single'),
|
"course/<slug>/video_tutorials/upload/",
|
||||||
path('course/<slug>/video_tutorials/<video_slug>/edit/', handle_video_edit, name='upload_video_edit'),
|
handle_video_upload,
|
||||||
path('course/<slug>/video_tutorials/<video_slug>/delete/', handle_video_delete, name='upload_video_delete'),
|
name="upload_video",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"course/<slug>/video_tutorials/<video_slug>/detail/",
|
||||||
|
handle_video_single,
|
||||||
|
name="video_single",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"course/<slug>/video_tutorials/<video_slug>/edit/",
|
||||||
|
handle_video_edit,
|
||||||
|
name="upload_video_edit",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"course/<slug>/video_tutorials/<video_slug>/delete/",
|
||||||
|
handle_video_delete,
|
||||||
|
name="upload_video_delete",
|
||||||
|
),
|
||||||
# course registration
|
# course registration
|
||||||
path('course/registration/', course_registration, name='course_registration'),
|
path("course/registration/", course_registration, name="course_registration"),
|
||||||
path('course/drop/', course_drop, name='course_drop'),
|
path("course/drop/", course_drop, name="course_drop"),
|
||||||
|
path("my_courses/", user_course_list, name="user_course_list"),
|
||||||
path('my_courses/', user_course_list, name="user_course_list"),
|
|
||||||
]
|
]
|
||||||
|
|||||||
@ -7,7 +7,7 @@ from django.utils.text import slugify
|
|||||||
|
|
||||||
|
|
||||||
def random_string_generator(size=10, chars=string.ascii_lowercase + string.digits):
|
def random_string_generator(size=10, chars=string.ascii_lowercase + string.digits):
|
||||||
return ''.join(random.choice(chars) for _ in range(size))
|
return "".join(random.choice(chars) for _ in range(size))
|
||||||
|
|
||||||
|
|
||||||
def unique_slug_generator(instance, new_slug=None):
|
def unique_slug_generator(instance, new_slug=None):
|
||||||
@ -24,8 +24,7 @@ def unique_slug_generator(instance, new_slug=None):
|
|||||||
qs_exists = Klass.objects.filter(slug=slug).exists()
|
qs_exists = Klass.objects.filter(slug=slug).exists()
|
||||||
if qs_exists:
|
if qs_exists:
|
||||||
new_slug = "{slug}-{randstr}".format(
|
new_slug = "{slug}-{randstr}".format(
|
||||||
slug=slug,
|
slug=slug, randstr=random_string_generator(size=4)
|
||||||
randstr=random_string_generator(size=4)
|
|
||||||
)
|
)
|
||||||
return unique_slug_generator(instance, new_slug=new_slug)
|
return unique_slug_generator(instance, new_slug=new_slug)
|
||||||
return slug
|
return slug
|
||||||
|
|||||||
359
course/views.py
359
course/views.py
@ -13,8 +13,12 @@ from app.models import Session, Semester
|
|||||||
from result.models import TakenCourse
|
from result.models import TakenCourse
|
||||||
from accounts.decorators import lecturer_required, student_required
|
from accounts.decorators import lecturer_required, student_required
|
||||||
from .forms import (
|
from .forms import (
|
||||||
ProgramForm, CourseAddForm, CourseAllocationForm,
|
ProgramForm,
|
||||||
EditCourseAllocationForm, UploadFormFile, UploadFormVideo
|
CourseAddForm,
|
||||||
|
CourseAllocationForm,
|
||||||
|
EditCourseAllocationForm,
|
||||||
|
UploadFormFile,
|
||||||
|
UploadFormVideo,
|
||||||
)
|
)
|
||||||
from .models import Program, Course, CourseAllocation, Upload, UploadVideo
|
from .models import Program, Course, CourseAllocation, Upload, UploadVideo
|
||||||
|
|
||||||
@ -26,51 +30,67 @@ from .models import Program, Course, CourseAllocation, Upload, UploadVideo
|
|||||||
def program_view(request):
|
def program_view(request):
|
||||||
programs = Program.objects.all()
|
programs = Program.objects.all()
|
||||||
|
|
||||||
program_filter = request.GET.get('program_filter')
|
program_filter = request.GET.get("program_filter")
|
||||||
if program_filter:
|
if program_filter:
|
||||||
programs = Program.objects.filter(title__icontains=program_filter)
|
programs = Program.objects.filter(title__icontains=program_filter)
|
||||||
|
|
||||||
return render(request, 'course/program_list.html', {
|
return render(
|
||||||
'title': "Programs | DjangoSMS",
|
request,
|
||||||
'programs': programs,
|
"course/program_list.html",
|
||||||
})
|
{
|
||||||
|
"title": "Programs | DjangoSMS",
|
||||||
|
"programs": programs,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@lecturer_required
|
@lecturer_required
|
||||||
def program_add(request):
|
def program_add(request):
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
form = ProgramForm(request.POST)
|
form = ProgramForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, request.POST.get('title') + ' program has been created.')
|
messages.success(
|
||||||
return redirect('programs')
|
request, request.POST.get("title") + " program has been created."
|
||||||
|
)
|
||||||
|
return redirect("programs")
|
||||||
else:
|
else:
|
||||||
messages.error(request, 'Correct the error(S) below.')
|
messages.error(request, "Correct the error(S) below.")
|
||||||
else:
|
else:
|
||||||
form = ProgramForm()
|
form = ProgramForm()
|
||||||
|
|
||||||
return render(request, 'course/program_add.html', {
|
return render(
|
||||||
'title': "Add Program | DjangoSMS",
|
request,
|
||||||
'form': form,
|
"course/program_add.html",
|
||||||
})
|
{
|
||||||
|
"title": "Add Program | DjangoSMS",
|
||||||
|
"form": form,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def program_detail(request, pk):
|
def program_detail(request, pk):
|
||||||
program = Program.objects.get(pk=pk)
|
program = Program.objects.get(pk=pk)
|
||||||
courses = Course.objects.filter(program_id=pk).order_by('-year')
|
courses = Course.objects.filter(program_id=pk).order_by("-year")
|
||||||
credits = Course.objects.aggregate(Sum('credit'))
|
credits = Course.objects.aggregate(Sum("credit"))
|
||||||
|
|
||||||
paginator = Paginator(courses, 10)
|
paginator = Paginator(courses, 10)
|
||||||
page = request.GET.get('page')
|
page = request.GET.get("page")
|
||||||
|
|
||||||
courses = paginator.get_page(page)
|
courses = paginator.get_page(page)
|
||||||
|
|
||||||
return render(request, 'course/program_single.html', {
|
return render(
|
||||||
'title': program.title,
|
request,
|
||||||
'program': program, 'courses': courses, 'credits': credits
|
"course/program_single.html",
|
||||||
}, )
|
{
|
||||||
|
"title": program.title,
|
||||||
|
"program": program,
|
||||||
|
"courses": courses,
|
||||||
|
"credits": credits,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -78,19 +98,22 @@ def program_detail(request, pk):
|
|||||||
def program_edit(request, pk):
|
def program_edit(request, pk):
|
||||||
program = Program.objects.get(pk=pk)
|
program = Program.objects.get(pk=pk)
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
form = ProgramForm(request.POST, instance=program)
|
form = ProgramForm(request.POST, instance=program)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, str(request.POST.get('title')) + ' program has been updated.')
|
messages.success(
|
||||||
return redirect('programs')
|
request, str(request.POST.get("title")) + " program has been updated."
|
||||||
|
)
|
||||||
|
return redirect("programs")
|
||||||
else:
|
else:
|
||||||
form = ProgramForm(instance=program)
|
form = ProgramForm(instance=program)
|
||||||
|
|
||||||
return render(request, 'course/program_add.html', {
|
return render(
|
||||||
'title': "Edit Program | DjangoSMS",
|
request,
|
||||||
'form': form
|
"course/program_add.html",
|
||||||
})
|
{"title": "Edit Program | DjangoSMS", "form": form},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -99,11 +122,14 @@ def program_delete(request, pk):
|
|||||||
program = Program.objects.get(pk=pk)
|
program = Program.objects.get(pk=pk)
|
||||||
title = program.title
|
title = program.title
|
||||||
program.delete()
|
program.delete()
|
||||||
messages.success(request, 'Program ' + title + ' has been deleted.')
|
messages.success(request, "Program " + title + " has been deleted.")
|
||||||
|
|
||||||
|
return redirect("programs")
|
||||||
|
|
||||||
|
|
||||||
return redirect('programs')
|
|
||||||
# ########################################################
|
# ########################################################
|
||||||
|
|
||||||
|
|
||||||
# ########################################################
|
# ########################################################
|
||||||
# Course views
|
# Course views
|
||||||
# ########################################################
|
# ########################################################
|
||||||
@ -116,61 +142,79 @@ def course_single(request, slug):
|
|||||||
# lecturers = User.objects.filter(allocated_lecturer__pk=course.id)
|
# lecturers = User.objects.filter(allocated_lecturer__pk=course.id)
|
||||||
lecturers = CourseAllocation.objects.filter(courses__pk=course.id)
|
lecturers = CourseAllocation.objects.filter(courses__pk=course.id)
|
||||||
|
|
||||||
return render(request, 'course/course_single.html', {
|
return render(
|
||||||
'title': course.title,
|
request,
|
||||||
'course': course,
|
"course/course_single.html",
|
||||||
'files': files,
|
{
|
||||||
'videos': videos,
|
"title": course.title,
|
||||||
'lecturers': lecturers,
|
"course": course,
|
||||||
'media_url': settings.MEDIA_ROOT,
|
"files": files,
|
||||||
}, )
|
"videos": videos,
|
||||||
|
"lecturers": lecturers,
|
||||||
|
"media_url": settings.MEDIA_ROOT,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@lecturer_required
|
@lecturer_required
|
||||||
def course_add(request, pk):
|
def course_add(request, pk):
|
||||||
users = User.objects.all()
|
users = User.objects.all()
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
form = CourseAddForm(request.POST)
|
form = CourseAddForm(request.POST)
|
||||||
course_name = request.POST.get('title')
|
course_name = request.POST.get("title")
|
||||||
course_code = request.POST.get('code')
|
course_code = request.POST.get("code")
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, (course_name + '(' + course_code + ')' + ' has been created.'))
|
messages.success(
|
||||||
return redirect('program_detail', pk=request.POST.get('program'))
|
request, (course_name + "(" + course_code + ")" + " has been created.")
|
||||||
|
)
|
||||||
|
return redirect("program_detail", pk=request.POST.get("program"))
|
||||||
else:
|
else:
|
||||||
messages.error(request, 'Correct the error(s) below.')
|
messages.error(request, "Correct the error(s) below.")
|
||||||
else:
|
else:
|
||||||
form = CourseAddForm(initial={'program': Program.objects.get(pk=pk)})
|
form = CourseAddForm(initial={"program": Program.objects.get(pk=pk)})
|
||||||
|
|
||||||
return render(request, 'course/course_add.html', {
|
return render(
|
||||||
'title': "Add Course | DjangoSMS",
|
request,
|
||||||
'form': form, 'program': pk, 'users': users
|
"course/course_add.html",
|
||||||
}, )
|
{
|
||||||
|
"title": "Add Course | DjangoSMS",
|
||||||
|
"form": form,
|
||||||
|
"program": pk,
|
||||||
|
"users": users,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@lecturer_required
|
@lecturer_required
|
||||||
def course_edit(request, slug):
|
def course_edit(request, slug):
|
||||||
course = get_object_or_404(Course, slug=slug)
|
course = get_object_or_404(Course, slug=slug)
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
form = CourseAddForm(request.POST, instance=course)
|
form = CourseAddForm(request.POST, instance=course)
|
||||||
course_name = request.POST.get('title')
|
course_name = request.POST.get("title")
|
||||||
course_code = request.POST.get('code')
|
course_code = request.POST.get("code")
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, (course_name + '(' + course_code + ')' + ' has been updated.'))
|
messages.success(
|
||||||
return redirect('program_detail', pk=request.POST.get('program'))
|
request, (course_name + "(" + course_code + ")" + " has been updated.")
|
||||||
|
)
|
||||||
|
return redirect("program_detail", pk=request.POST.get("program"))
|
||||||
else:
|
else:
|
||||||
messages.error(request, 'Correct the error(s) below.')
|
messages.error(request, "Correct the error(s) below.")
|
||||||
else:
|
else:
|
||||||
form = CourseAddForm(instance=course)
|
form = CourseAddForm(instance=course)
|
||||||
|
|
||||||
return render(request, 'course/course_add.html', {
|
return render(
|
||||||
'title': "Edit Course | DjangoSMS",
|
request,
|
||||||
|
"course/course_add.html",
|
||||||
|
{
|
||||||
|
"title": "Edit Course | DjangoSMS",
|
||||||
# 'form': form, 'program': pk, 'course': pk
|
# 'form': form, 'program': pk, 'course': pk
|
||||||
'form': form
|
"form": form,
|
||||||
}, )
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -179,29 +223,31 @@ def course_delete(request, slug):
|
|||||||
course = Course.objects.get(slug=slug)
|
course = Course.objects.get(slug=slug)
|
||||||
# course_name = course.title
|
# course_name = course.title
|
||||||
course.delete()
|
course.delete()
|
||||||
messages.success(request, 'Course ' + course.title + ' has been deleted.')
|
messages.success(request, "Course " + course.title + " has been deleted.")
|
||||||
|
|
||||||
|
return redirect("program_detail", pk=course.program.id)
|
||||||
|
|
||||||
|
|
||||||
return redirect('program_detail', pk=course.program.id)
|
|
||||||
# ########################################################
|
# ########################################################
|
||||||
|
|
||||||
|
|
||||||
# ########################################################
|
# ########################################################
|
||||||
# Course Allocation
|
# Course Allocation
|
||||||
# ########################################################
|
# ########################################################
|
||||||
@method_decorator([login_required], name='dispatch')
|
@method_decorator([login_required], name="dispatch")
|
||||||
class CourseAllocationFormView(CreateView):
|
class CourseAllocationFormView(CreateView):
|
||||||
form_class = CourseAllocationForm
|
form_class = CourseAllocationForm
|
||||||
template_name = 'course/course_allocation_form.html'
|
template_name = "course/course_allocation_form.html"
|
||||||
|
|
||||||
def get_form_kwargs(self):
|
def get_form_kwargs(self):
|
||||||
kwargs = super(CourseAllocationFormView, self).get_form_kwargs()
|
kwargs = super(CourseAllocationFormView, self).get_form_kwargs()
|
||||||
kwargs['user'] = self.request.user
|
kwargs["user"] = self.request.user
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
# if a staff has been allocated a course before update it else create new
|
# if a staff has been allocated a course before update it else create new
|
||||||
lecturer = form.cleaned_data['lecturer']
|
lecturer = form.cleaned_data["lecturer"]
|
||||||
selected_courses = form.cleaned_data['courses']
|
selected_courses = form.cleaned_data["courses"]
|
||||||
courses = ()
|
courses = ()
|
||||||
for course in selected_courses:
|
for course in selected_courses:
|
||||||
courses += (course.pk,)
|
courses += (course.pk,)
|
||||||
@ -214,40 +260,45 @@ class CourseAllocationFormView(CreateView):
|
|||||||
for i in range(0, selected_courses.count()):
|
for i in range(0, selected_courses.count()):
|
||||||
a.courses.add(courses[i])
|
a.courses.add(courses[i])
|
||||||
a.save()
|
a.save()
|
||||||
return redirect('course_allocation_view')
|
return redirect("course_allocation_view")
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context['title'] = "Assign Course | DjangoSMS"
|
context["title"] = "Assign Course | DjangoSMS"
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def course_allocation_view(request):
|
def course_allocation_view(request):
|
||||||
allocated_courses = CourseAllocation.objects.all()
|
allocated_courses = CourseAllocation.objects.all()
|
||||||
return render(request, 'course/course_allocation_view.html', {
|
return render(
|
||||||
'title': "Course Allocations | DjangoSMS",
|
request,
|
||||||
"allocated_courses": allocated_courses
|
"course/course_allocation_view.html",
|
||||||
})
|
{
|
||||||
|
"title": "Course Allocations | DjangoSMS",
|
||||||
|
"allocated_courses": allocated_courses,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@lecturer_required
|
@lecturer_required
|
||||||
def edit_allocated_course(request, pk):
|
def edit_allocated_course(request, pk):
|
||||||
allocated = get_object_or_404(CourseAllocation, pk=pk)
|
allocated = get_object_or_404(CourseAllocation, pk=pk)
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
form = EditCourseAllocationForm(request.POST, instance=allocated)
|
form = EditCourseAllocationForm(request.POST, instance=allocated)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, 'course assigned has been updated.')
|
messages.success(request, "course assigned has been updated.")
|
||||||
return redirect('course_allocation_view')
|
return redirect("course_allocation_view")
|
||||||
else:
|
else:
|
||||||
form = EditCourseAllocationForm(instance=allocated)
|
form = EditCourseAllocationForm(instance=allocated)
|
||||||
|
|
||||||
return render(request, 'course/course_allocation_form.html', {
|
return render(
|
||||||
'title': "Edit Course Allocated | DjangoSMS",
|
request,
|
||||||
'form': form, 'allocated': pk
|
"course/course_allocation_form.html",
|
||||||
}, )
|
{"title": "Edit Course Allocated | DjangoSMS", "form": form, "allocated": pk},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -255,8 +306,10 @@ def edit_allocated_course(request, pk):
|
|||||||
def deallocate_course(request, pk):
|
def deallocate_course(request, pk):
|
||||||
course = CourseAllocation.objects.get(pk=pk)
|
course = CourseAllocation.objects.get(pk=pk)
|
||||||
course.delete()
|
course.delete()
|
||||||
messages.success(request, 'successfully deallocate!')
|
messages.success(request, "successfully deallocate!")
|
||||||
return redirect("course_allocation_view")
|
return redirect("course_allocation_view")
|
||||||
|
|
||||||
|
|
||||||
# ########################################################
|
# ########################################################
|
||||||
|
|
||||||
|
|
||||||
@ -267,19 +320,22 @@ def deallocate_course(request, pk):
|
|||||||
@lecturer_required
|
@lecturer_required
|
||||||
def handle_file_upload(request, slug):
|
def handle_file_upload(request, slug):
|
||||||
course = Course.objects.get(slug=slug)
|
course = Course.objects.get(slug=slug)
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
form = UploadFormFile(request.POST, request.FILES, {'course': course})
|
form = UploadFormFile(request.POST, request.FILES, {"course": course})
|
||||||
# file_name = request.POST.get('name')
|
# file_name = request.POST.get('name')
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, (request.POST.get('title') + ' has been uploaded.'))
|
messages.success(
|
||||||
return redirect('course_detail', slug=slug)
|
request, (request.POST.get("title") + " has been uploaded.")
|
||||||
|
)
|
||||||
|
return redirect("course_detail", slug=slug)
|
||||||
else:
|
else:
|
||||||
form = UploadFormFile()
|
form = UploadFormFile()
|
||||||
return render(request, 'upload/upload_file_form.html', {
|
return render(
|
||||||
'title': "File Upload | DjangoSMS",
|
request,
|
||||||
'form': form, 'course': course
|
"upload/upload_file_form.html",
|
||||||
})
|
{"title": "File Upload | DjangoSMS", "form": form, "course": course},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -287,19 +343,23 @@ def handle_file_upload(request, slug):
|
|||||||
def handle_file_edit(request, slug, file_id):
|
def handle_file_edit(request, slug, file_id):
|
||||||
course = Course.objects.get(slug=slug)
|
course = Course.objects.get(slug=slug)
|
||||||
instance = Upload.objects.get(pk=file_id)
|
instance = Upload.objects.get(pk=file_id)
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
form = UploadFormFile(request.POST, request.FILES, instance=instance)
|
form = UploadFormFile(request.POST, request.FILES, instance=instance)
|
||||||
# file_name = request.POST.get('name')
|
# file_name = request.POST.get('name')
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, (request.POST.get('title') + ' has been updated.'))
|
messages.success(
|
||||||
return redirect('course_detail', slug=slug)
|
request, (request.POST.get("title") + " has been updated.")
|
||||||
|
)
|
||||||
|
return redirect("course_detail", slug=slug)
|
||||||
else:
|
else:
|
||||||
form = UploadFormFile(instance=instance)
|
form = UploadFormFile(instance=instance)
|
||||||
|
|
||||||
return render(request, 'upload/upload_file_form.html', {
|
return render(
|
||||||
'title': instance.title,
|
request,
|
||||||
'form': form, 'course': course})
|
"upload/upload_file_form.html",
|
||||||
|
{"title": instance.title, "form": form, "course": course},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def handle_file_delete(request, slug, file_id):
|
def handle_file_delete(request, slug, file_id):
|
||||||
@ -307,8 +367,9 @@ def handle_file_delete(request, slug, file_id):
|
|||||||
# file_name = file.name
|
# file_name = file.name
|
||||||
file.delete()
|
file.delete()
|
||||||
|
|
||||||
messages.success(request, (file.title + ' has been deleted.'))
|
messages.success(request, (file.title + " has been deleted."))
|
||||||
return redirect('course_detail', slug=slug)
|
return redirect("course_detail", slug=slug)
|
||||||
|
|
||||||
|
|
||||||
# ########################################################
|
# ########################################################
|
||||||
# Video Upload views
|
# Video Upload views
|
||||||
@ -317,18 +378,21 @@ def handle_file_delete(request, slug, file_id):
|
|||||||
@lecturer_required
|
@lecturer_required
|
||||||
def handle_video_upload(request, slug):
|
def handle_video_upload(request, slug):
|
||||||
course = Course.objects.get(slug=slug)
|
course = Course.objects.get(slug=slug)
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
form = UploadFormVideo(request.POST, request.FILES, {'course': course})
|
form = UploadFormVideo(request.POST, request.FILES, {"course": course})
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, (request.POST.get('title') + ' has been uploaded.'))
|
messages.success(
|
||||||
return redirect('course_detail', slug=slug)
|
request, (request.POST.get("title") + " has been uploaded.")
|
||||||
|
)
|
||||||
|
return redirect("course_detail", slug=slug)
|
||||||
else:
|
else:
|
||||||
form = UploadFormVideo()
|
form = UploadFormVideo()
|
||||||
return render(request, 'upload/upload_video_form.html', {
|
return render(
|
||||||
'title': "Video Upload | DjangoSMS",
|
request,
|
||||||
'form': form, 'course': course
|
"upload/upload_video_form.html",
|
||||||
})
|
{"title": "Video Upload | DjangoSMS", "form": form, "course": course},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -336,7 +400,7 @@ def handle_video_upload(request, slug):
|
|||||||
def handle_video_single(request, slug, video_slug):
|
def handle_video_single(request, slug, video_slug):
|
||||||
course = get_object_or_404(Course, slug=slug)
|
course = get_object_or_404(Course, slug=slug)
|
||||||
video = get_object_or_404(UploadVideo, slug=video_slug)
|
video = get_object_or_404(UploadVideo, slug=video_slug)
|
||||||
return render(request, 'upload/video_single.html', {'video': video})
|
return render(request, "upload/video_single.html", {"video": video})
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -344,18 +408,22 @@ def handle_video_single(request, slug, video_slug):
|
|||||||
def handle_video_edit(request, slug, video_slug):
|
def handle_video_edit(request, slug, video_slug):
|
||||||
course = Course.objects.get(slug=slug)
|
course = Course.objects.get(slug=slug)
|
||||||
instance = UploadVideo.objects.get(slug=video_slug)
|
instance = UploadVideo.objects.get(slug=video_slug)
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
form = UploadFormVideo(request.POST, request.FILES, instance=instance)
|
form = UploadFormVideo(request.POST, request.FILES, instance=instance)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.save()
|
form.save()
|
||||||
messages.success(request, (request.POST.get('title') + ' has been updated.'))
|
messages.success(
|
||||||
return redirect('course_detail', slug=slug)
|
request, (request.POST.get("title") + " has been updated.")
|
||||||
|
)
|
||||||
|
return redirect("course_detail", slug=slug)
|
||||||
else:
|
else:
|
||||||
form = UploadFormVideo(instance=instance)
|
form = UploadFormVideo(instance=instance)
|
||||||
|
|
||||||
return render(request, 'upload/upload_video_form.html', {
|
return render(
|
||||||
'title': instance.title,
|
request,
|
||||||
'form': form, 'course': course})
|
"upload/upload_video_form.html",
|
||||||
|
{"title": instance.title, "form": form, "course": course},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def handle_video_delete(request, slug, video_slug):
|
def handle_video_delete(request, slug, video_slug):
|
||||||
@ -363,8 +431,10 @@ def handle_video_delete(request, slug, video_slug):
|
|||||||
# video = UploadVideo.objects.get(slug=video_slug)
|
# video = UploadVideo.objects.get(slug=video_slug)
|
||||||
video.delete()
|
video.delete()
|
||||||
|
|
||||||
messages.success(request, (video.title + ' has been deleted.'))
|
messages.success(request, (video.title + " has been deleted."))
|
||||||
return redirect('course_detail', slug=slug)
|
return redirect("course_detail", slug=slug)
|
||||||
|
|
||||||
|
|
||||||
# ########################################################
|
# ########################################################
|
||||||
|
|
||||||
|
|
||||||
@ -374,10 +444,10 @@ def handle_video_delete(request, slug, video_slug):
|
|||||||
@login_required
|
@login_required
|
||||||
@student_required
|
@student_required
|
||||||
def course_registration(request):
|
def course_registration(request):
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
ids = ()
|
ids = ()
|
||||||
data = request.POST.copy()
|
data = request.POST.copy()
|
||||||
data.pop('csrfmiddlewaretoken', None) # remove csrf_token
|
data.pop("csrfmiddlewaretoken", None) # remove csrf_token
|
||||||
for key in data.keys():
|
for key in data.keys():
|
||||||
ids = ids + (str(key),)
|
ids = ids + (str(key),)
|
||||||
for s in range(0, len(ids)):
|
for s in range(0, len(ids)):
|
||||||
@ -385,8 +455,8 @@ def course_registration(request):
|
|||||||
course = Course.objects.get(pk=ids[s])
|
course = Course.objects.get(pk=ids[s])
|
||||||
obj = TakenCourse.objects.create(student=student, course=course)
|
obj = TakenCourse.objects.create(student=student, course=course)
|
||||||
obj.save()
|
obj.save()
|
||||||
messages.success(request, 'Courses Registered Successfully!')
|
messages.success(request, "Courses Registered Successfully!")
|
||||||
return redirect('course_registration')
|
return redirect("course_registration")
|
||||||
else:
|
else:
|
||||||
# student = Student.objects.get(student__pk=request.user.id)
|
# student = Student.objects.get(student__pk=request.user.id)
|
||||||
student = get_object_or_404(Student, student__id=request.user.id)
|
student = get_object_or_404(Student, student__id=request.user.id)
|
||||||
@ -396,15 +466,26 @@ def course_registration(request):
|
|||||||
t += (i.course.pk,)
|
t += (i.course.pk,)
|
||||||
current_semester = Semester.objects.get(is_current_semester=True)
|
current_semester = Semester.objects.get(is_current_semester=True)
|
||||||
|
|
||||||
courses = Course.objects.filter(program__pk=student.department.id, level=student.level, semester=current_semester
|
courses = (
|
||||||
).exclude(id__in=t).order_by('year')
|
Course.objects.filter(
|
||||||
all_courses = Course.objects.filter(level=student.level, program__pk=student.department.id)
|
program__pk=student.department.id,
|
||||||
|
level=student.level,
|
||||||
|
semester=current_semester,
|
||||||
|
)
|
||||||
|
.exclude(id__in=t)
|
||||||
|
.order_by("year")
|
||||||
|
)
|
||||||
|
all_courses = Course.objects.filter(
|
||||||
|
level=student.level, program__pk=student.department.id
|
||||||
|
)
|
||||||
|
|
||||||
no_course_is_registered = False # Check if no course is registered
|
no_course_is_registered = False # Check if no course is registered
|
||||||
all_courses_are_registered = False
|
all_courses_are_registered = False
|
||||||
|
|
||||||
registered_courses = Course.objects.filter(level=student.level).filter(id__in=t)
|
registered_courses = Course.objects.filter(level=student.level).filter(id__in=t)
|
||||||
if registered_courses.count() == 0: # Check if number of registered courses is 0
|
if (
|
||||||
|
registered_courses.count() == 0
|
||||||
|
): # Check if number of registered courses is 0
|
||||||
no_course_is_registered = True
|
no_course_is_registered = True
|
||||||
|
|
||||||
if registered_courses.count() == all_courses.count():
|
if registered_courses.count() == all_courses.count():
|
||||||
@ -432,16 +513,16 @@ def course_registration(request):
|
|||||||
"total_registered_credit": total_registered_credit,
|
"total_registered_credit": total_registered_credit,
|
||||||
"student": student,
|
"student": student,
|
||||||
}
|
}
|
||||||
return render(request, 'course/course_registration.html', context)
|
return render(request, "course/course_registration.html", context)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@student_required
|
@student_required
|
||||||
def course_drop(request):
|
def course_drop(request):
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
ids = ()
|
ids = ()
|
||||||
data = request.POST.copy()
|
data = request.POST.copy()
|
||||||
data.pop('csrfmiddlewaretoken', None) # remove csrf_token
|
data.pop("csrfmiddlewaretoken", None) # remove csrf_token
|
||||||
for key in data.keys():
|
for key in data.keys():
|
||||||
ids = ids + (str(key),)
|
ids = ids + (str(key),)
|
||||||
for s in range(0, len(ids)):
|
for s in range(0, len(ids)):
|
||||||
@ -449,8 +530,10 @@ def course_drop(request):
|
|||||||
course = Course.objects.get(pk=ids[s])
|
course = Course.objects.get(pk=ids[s])
|
||||||
obj = TakenCourse.objects.get(student=student, course=course)
|
obj = TakenCourse.objects.get(student=student, course=course)
|
||||||
obj.delete()
|
obj.delete()
|
||||||
messages.success(request, 'Successfully Dropped!')
|
messages.success(request, "Successfully Dropped!")
|
||||||
return redirect('course_registration')
|
return redirect("course_registration")
|
||||||
|
|
||||||
|
|
||||||
# ########################################################
|
# ########################################################
|
||||||
|
|
||||||
|
|
||||||
@ -459,18 +542,22 @@ def user_course_list(request):
|
|||||||
if request.user.is_lecturer:
|
if request.user.is_lecturer:
|
||||||
courses = Course.objects.filter(allocated_course__lecturer__pk=request.user.id)
|
courses = Course.objects.filter(allocated_course__lecturer__pk=request.user.id)
|
||||||
|
|
||||||
return render(request, 'course/user_course_list.html', {'courses': courses})
|
return render(request, "course/user_course_list.html", {"courses": courses})
|
||||||
|
|
||||||
elif request.user.is_student:
|
elif request.user.is_student:
|
||||||
student = Student.objects.get(student__pk=request.user.id)
|
student = Student.objects.get(student__pk=request.user.id)
|
||||||
taken_courses = TakenCourse.objects.filter(student__student__id=student.student.id)
|
taken_courses = TakenCourse.objects.filter(
|
||||||
courses = Course.objects.filter(level=student.level).filter(program__pk=student.department.id)
|
student__student__id=student.student.id
|
||||||
|
)
|
||||||
|
courses = Course.objects.filter(level=student.level).filter(
|
||||||
|
program__pk=student.department.id
|
||||||
|
)
|
||||||
|
|
||||||
return render(request, 'course/user_course_list.html', {
|
return render(
|
||||||
'student': student,
|
request,
|
||||||
'taken_courses': taken_courses,
|
"course/user_course_list.html",
|
||||||
'courses': courses
|
{"student": student, "taken_courses": taken_courses, "courses": courses},
|
||||||
})
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return render(request, 'course/user_course_list.html')
|
return render(request, "course/user_course_list.html")
|
||||||
|
|||||||
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
|
|
||||||
class PaymentsConfig(AppConfig):
|
class PaymentsConfig(AppConfig):
|
||||||
name = 'payments'
|
name = "payments"
|
||||||
|
|||||||
@ -2,18 +2,15 @@ from django.urls import path
|
|||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.PaymentGetwaysView.as_view(), name='payment_gateways'),
|
path("", views.PaymentGetwaysView.as_view(), name="payment_gateways"),
|
||||||
|
path("paypal/", views.payment_paypal, name="paypal"),
|
||||||
path('paypal/', views.payment_paypal, name="paypal"),
|
path("stripe/", views.payment_stripe, name="stripe"),
|
||||||
path('stripe/', views.payment_stripe, name="stripe"),
|
path("coinbase/", views.payment_coinbase, name="coinbase"),
|
||||||
path('coinbase/', views.payment_coinbase, name="coinbase"),
|
path("paylike/", views.payment_paylike, name="paylike"),
|
||||||
path('paylike/', views.payment_paylike, name="paylike"),
|
path("stripe-charge/", views.stripe_charge, name="stripe_charge"),
|
||||||
|
path("gopay-charge/", views.gopay_charge, name="gopay_charge"),
|
||||||
path('stripe-charge/', views.stripe_charge, name='stripe_charge'),
|
path("payment-succeed/", views.payment_succeed, name="payment-succeed"),
|
||||||
path('gopay-charge/', views.gopay_charge, name="gopay_charge"),
|
path("complete/", views.paymentComplete, name="complete"),
|
||||||
|
path("create-invoice/", views.create_invoice, name="create_invoice"),
|
||||||
path('payment-succeed/', views.payment_succeed, name="payment-succeed"),
|
path("invoice-detail/<int:id>/", views.invoice_detail, name="invoice_detail"),
|
||||||
path('complete/', views.paymentComplete, name="complete"),
|
|
||||||
path('create-invoice/', views.create_invoice, name="create_invoice"),
|
|
||||||
path('invoice-detail/<int:id>/', views.invoice_detail, name="invoice_detail"),
|
|
||||||
]
|
]
|
||||||
|
|||||||
@ -16,126 +16,128 @@ from .models import Invoice
|
|||||||
|
|
||||||
|
|
||||||
def payment_paypal(request):
|
def payment_paypal(request):
|
||||||
return render(request, 'payments/paypal.html', context={})
|
return render(request, "payments/paypal.html", context={})
|
||||||
|
|
||||||
|
|
||||||
def payment_stripe(request):
|
def payment_stripe(request):
|
||||||
return render(request, 'payments/stripe.html', context={})
|
return render(request, "payments/stripe.html", context={})
|
||||||
|
|
||||||
|
|
||||||
def payment_coinbase(request):
|
def payment_coinbase(request):
|
||||||
return render(request, 'payments/coinbase.html', context={})
|
return render(request, "payments/coinbase.html", context={})
|
||||||
|
|
||||||
|
|
||||||
def payment_paylike(request):
|
def payment_paylike(request):
|
||||||
return render(request, 'payments/paylike.html', context={})
|
return render(request, "payments/paylike.html", context={})
|
||||||
|
|
||||||
|
|
||||||
def payment_succeed(request):
|
def payment_succeed(request):
|
||||||
return render(request, 'payments/payment_succeed.html', context={})
|
return render(request, "payments/payment_succeed.html", context={})
|
||||||
|
|
||||||
|
|
||||||
class PaymentGetwaysView(TemplateView):
|
class PaymentGetwaysView(TemplateView):
|
||||||
template_name = 'payments/payment_gateways.html'
|
template_name = "payments/payment_gateways.html"
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(PaymentGetwaysView, self).get_context_data(**kwargs)
|
context = super(PaymentGetwaysView, self).get_context_data(**kwargs)
|
||||||
context['key'] = settings.STRIPE_PUBLISHABLE_KEY
|
context["key"] = settings.STRIPE_PUBLISHABLE_KEY
|
||||||
context['amount'] = 500
|
context["amount"] = 500
|
||||||
context['description'] = "Stripe Payment"
|
context["description"] = "Stripe Payment"
|
||||||
context['invoice_session'] = self.request.session['invoice_session']
|
context["invoice_session"] = self.request.session["invoice_session"]
|
||||||
print(context['invoice_session'])
|
print(context["invoice_session"])
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
def stripe_charge(request):
|
def stripe_charge(request):
|
||||||
stripe.api_key = settings.STRIPE_SECRET_KEY
|
stripe.api_key = settings.STRIPE_SECRET_KEY
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
charge = stripe.Charge.create(
|
charge = stripe.Charge.create(
|
||||||
amount=500,
|
amount=500,
|
||||||
currency='eur',
|
currency="eur",
|
||||||
description='A Django charge',
|
description="A Django charge",
|
||||||
source=request.POST['stripeToken']
|
source=request.POST["stripeToken"],
|
||||||
)
|
)
|
||||||
invoice_code = request.session['invoice_session']
|
invoice_code = request.session["invoice_session"]
|
||||||
invoice = Invoice.objects.get(invoice_code=invoice_code)
|
invoice = Invoice.objects.get(invoice_code=invoice_code)
|
||||||
invoice.payment_complete = True
|
invoice.payment_complete = True
|
||||||
invoice.save()
|
invoice.save()
|
||||||
return redirect('completed')
|
return redirect("completed")
|
||||||
# return JsonResponse({"invoice_code": invoice.invoice_code}, status=201)
|
# return JsonResponse({"invoice_code": invoice.invoice_code}, status=201)
|
||||||
# return render(request, 'payments/charge.html')
|
# return render(request, 'payments/charge.html')
|
||||||
|
|
||||||
|
|
||||||
def gopay_charge(request):
|
def gopay_charge(request):
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
user = request.user
|
user = request.user
|
||||||
|
|
||||||
payments = gopay.payments({
|
payments = gopay.payments(
|
||||||
'goid': '[PAYMENT_ID]',
|
{
|
||||||
'clientId': '[GOPAY_CLIENT_ID]',
|
"goid": "[PAYMENT_ID]",
|
||||||
'clientSecret': '[GOPAY_CLIENT_SECRET]',
|
"clientId": "[GOPAY_CLIENT_ID]",
|
||||||
'isProductionMode': False,
|
"clientSecret": "[GOPAY_CLIENT_SECRET]",
|
||||||
'scope': gopay.TokenScope.ALL,
|
"isProductionMode": False,
|
||||||
'language': gopay.Language.ENGLISH,
|
"scope": gopay.TokenScope.ALL,
|
||||||
'timeout': 30
|
"language": gopay.Language.ENGLISH,
|
||||||
})
|
"timeout": 30,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
# recurrent payment must have field ''
|
# recurrent payment must have field ''
|
||||||
recurrentPayment = {
|
recurrentPayment = {
|
||||||
'recurrence': {
|
"recurrence": {
|
||||||
'recurrence_cycle': Recurrence.DAILY,
|
"recurrence_cycle": Recurrence.DAILY,
|
||||||
'recurrence_period': "7",
|
"recurrence_period": "7",
|
||||||
'recurrence_date_to': '2015-12-31'
|
"recurrence_date_to": "2015-12-31",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# pre-authorized payment must have field 'preauthorization'
|
# pre-authorized payment must have field 'preauthorization'
|
||||||
preauthorizedPayment = {
|
preauthorizedPayment = {"preauthorization": True}
|
||||||
'preauthorization': True
|
|
||||||
}
|
|
||||||
|
|
||||||
response = payments.create_payment({
|
response = payments.create_payment(
|
||||||
'payer': {
|
{
|
||||||
'default_payment_instrument': PaymentInstrument.BANK_ACCOUNT,
|
"payer": {
|
||||||
'allowed_payment_instruments': [PaymentInstrument.BANK_ACCOUNT],
|
"default_payment_instrument": PaymentInstrument.BANK_ACCOUNT,
|
||||||
'default_swift': BankSwiftCode.FIO_BANKA,
|
"allowed_payment_instruments": [PaymentInstrument.BANK_ACCOUNT],
|
||||||
'allowed_swifts': [BankSwiftCode.FIO_BANKA, BankSwiftCode.MBANK],
|
"default_swift": BankSwiftCode.FIO_BANKA,
|
||||||
'contact': {
|
"allowed_swifts": [BankSwiftCode.FIO_BANKA, BankSwiftCode.MBANK],
|
||||||
'first_name': user.first_name,
|
"contact": {
|
||||||
'last_name': user.last_name,
|
"first_name": user.first_name,
|
||||||
'email': user.email,
|
"last_name": user.last_name,
|
||||||
'phone_number': user.phone,
|
"email": user.email,
|
||||||
'city': 'example city',
|
"phone_number": user.phone,
|
||||||
'street': 'Plana 67',
|
"city": "example city",
|
||||||
'postal_code': '373 01',
|
"street": "Plana 67",
|
||||||
'country_code': 'CZE',
|
"postal_code": "373 01",
|
||||||
|
"country_code": "CZE",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'amount': 150,
|
"amount": 150,
|
||||||
'currency': Currency.CZECH_CROWNS,
|
"currency": Currency.CZECH_CROWNS,
|
||||||
'order_number': '001',
|
"order_number": "001",
|
||||||
'order_description': 'pojisteni01',
|
"order_description": "pojisteni01",
|
||||||
'items': [
|
"items": [
|
||||||
{'name': 'item01', 'amount': 50},
|
{"name": "item01", "amount": 50},
|
||||||
{'name': 'item02', 'amount': 100},
|
{"name": "item02", "amount": 100},
|
||||||
],
|
],
|
||||||
'additional_params': [
|
"additional_params": [{"name": "invoicenumber", "value": "2015001003"}],
|
||||||
{'name': 'invoicenumber', 'value': '2015001003'}
|
"callback": {
|
||||||
],
|
"return_url": "http://www.your-url.tld/return",
|
||||||
'callback': {
|
"notification_url": "http://www.your-url.tld/notify",
|
||||||
'return_url': 'http://www.your-url.tld/return',
|
|
||||||
'notification_url': 'http://www.your-url.tld/notify'
|
|
||||||
},
|
},
|
||||||
'lang': Language.CZECH, # if lang is not specified, then default lang is used
|
"lang": Language.CZECH, # if lang is not specified, then default lang is used
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if response.has_succeed():
|
if response.has_succeed():
|
||||||
print("\nPayment Succeed\n")
|
print("\nPayment Succeed\n")
|
||||||
print("hooray, API returned " + str(response))
|
print("hooray, API returned " + str(response))
|
||||||
else:
|
else:
|
||||||
print("\nPayment Fail\n")
|
print("\nPayment Fail\n")
|
||||||
print("oops, API returned " + str(response.status_code) + ": " + str(response))
|
print(
|
||||||
|
"oops, API returned " + str(response.status_code) + ": " + str(response)
|
||||||
|
)
|
||||||
return JsonResponse({"message": str(response)})
|
return JsonResponse({"message": str(response)})
|
||||||
|
|
||||||
return JsonResponse({"message": "GET requested"})
|
return JsonResponse({"message": "GET requested"})
|
||||||
@ -143,28 +145,28 @@ def gopay_charge(request):
|
|||||||
|
|
||||||
def paymentComplete(request):
|
def paymentComplete(request):
|
||||||
print(request.is_ajax())
|
print(request.is_ajax())
|
||||||
if request.is_ajax() or request.method == 'POST':
|
if request.is_ajax() or request.method == "POST":
|
||||||
invoice_id = request.session['invoice_session']
|
invoice_id = request.session["invoice_session"]
|
||||||
invoice = Invoice.objects.get(id=invoice_id)
|
invoice = Invoice.objects.get(id=invoice_id)
|
||||||
invoice.payment_complete = True
|
invoice.payment_complete = True
|
||||||
invoice.save()
|
invoice.save()
|
||||||
# return redirect('invoice', invoice.invoice_code)
|
# return redirect('invoice', invoice.invoice_code)
|
||||||
body = json.loads(request.body)
|
body = json.loads(request.body)
|
||||||
print('BODY:', body)
|
print("BODY:", body)
|
||||||
return JsonResponse('Payment completed!', safe=False)
|
return JsonResponse("Payment completed!", safe=False)
|
||||||
|
|
||||||
|
|
||||||
def create_invoice(request):
|
def create_invoice(request):
|
||||||
print(request.is_ajax())
|
print(request.is_ajax())
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
invoice = Invoice.objects.create(
|
invoice = Invoice.objects.create(
|
||||||
user=request.user,
|
user=request.user,
|
||||||
amount = request.POST.get('amount'),
|
amount=request.POST.get("amount"),
|
||||||
total=26,
|
total=26,
|
||||||
invoice_code=str(uuid.uuid4()),
|
invoice_code=str(uuid.uuid4()),
|
||||||
)
|
)
|
||||||
request.session['invoice_session'] = invoice.invoice_code
|
request.session["invoice_session"] = invoice.invoice_code
|
||||||
return redirect('payment_gateways')
|
return redirect("payment_gateways")
|
||||||
# if request.is_ajax():
|
# if request.is_ajax():
|
||||||
# invoice = Invoice.objects.create(
|
# invoice = Invoice.objects.create(
|
||||||
# user = request.user,
|
# user = request.user,
|
||||||
@ -173,12 +175,16 @@ def create_invoice(request):
|
|||||||
# )
|
# )
|
||||||
# return JsonResponse({'invoice': invoice}, status=201) # created
|
# return JsonResponse({'invoice': invoice}, status=201) # created
|
||||||
|
|
||||||
return render(request, 'invoices.html', context={
|
return render(
|
||||||
'invoices': Invoice.objects.filter(user=request.user)
|
request,
|
||||||
})
|
"invoices.html",
|
||||||
|
context={"invoices": Invoice.objects.filter(user=request.user)},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def invoice_detail(request, slug):
|
def invoice_detail(request, slug):
|
||||||
return render(request, 'invoice_detail.html', context={
|
return render(
|
||||||
'invoice': Invoice.objects.get(invoice_code=slug)
|
request,
|
||||||
})
|
"invoice_detail.html",
|
||||||
|
context={"invoice": Invoice.objects.get(invoice_code=slug)},
|
||||||
|
)
|
||||||
|
|||||||
@ -3,7 +3,15 @@ from django.contrib import admin
|
|||||||
from django.contrib.admin.widgets import FilteredSelectMultiple
|
from django.contrib.admin.widgets import FilteredSelectMultiple
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from .models import Quiz, Progress, Question, MCQuestion, Choice, Essay_Question, Sitting
|
from .models import (
|
||||||
|
Quiz,
|
||||||
|
Progress,
|
||||||
|
Question,
|
||||||
|
MCQuestion,
|
||||||
|
Choice,
|
||||||
|
Essay_Question,
|
||||||
|
Sitting,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ChoiceInline(admin.TabularInline):
|
class ChoiceInline(admin.TabularInline):
|
||||||
@ -11,7 +19,6 @@ class ChoiceInline(admin.TabularInline):
|
|||||||
|
|
||||||
|
|
||||||
class QuizAdminForm(forms.ModelForm):
|
class QuizAdminForm(forms.ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Quiz
|
model = Quiz
|
||||||
exclude = []
|
exclude = []
|
||||||
@ -20,19 +27,20 @@ class QuizAdminForm(forms.ModelForm):
|
|||||||
queryset=Question.objects.all().select_subclasses(),
|
queryset=Question.objects.all().select_subclasses(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_("Questions"),
|
label=_("Questions"),
|
||||||
widget=FilteredSelectMultiple(
|
widget=FilteredSelectMultiple(verbose_name=_("Questions"), is_stacked=False),
|
||||||
verbose_name=_("Questions"),
|
)
|
||||||
is_stacked=False))
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(QuizAdminForm, self).__init__(*args, **kwargs)
|
super(QuizAdminForm, self).__init__(*args, **kwargs)
|
||||||
if self.instance.pk:
|
if self.instance.pk:
|
||||||
self.fields['questions'].initial = self.instance.question_set.all().select_subclasses()
|
self.fields[
|
||||||
|
"questions"
|
||||||
|
].initial = self.instance.question_set.all().select_subclasses()
|
||||||
|
|
||||||
def save(self, commit=True):
|
def save(self, commit=True):
|
||||||
quiz = super(QuizAdminForm, self).save(commit=False)
|
quiz = super(QuizAdminForm, self).save(commit=False)
|
||||||
quiz.save()
|
quiz.save()
|
||||||
quiz.question_set.set(self.cleaned_data['questions'])
|
quiz.question_set.set(self.cleaned_data["questions"])
|
||||||
self.save_m2m()
|
self.save_m2m()
|
||||||
return quiz
|
return quiz
|
||||||
|
|
||||||
@ -40,32 +48,43 @@ class QuizAdminForm(forms.ModelForm):
|
|||||||
class QuizAdmin(admin.ModelAdmin):
|
class QuizAdmin(admin.ModelAdmin):
|
||||||
form = QuizAdminForm
|
form = QuizAdminForm
|
||||||
|
|
||||||
list_display = ('title', )
|
list_display = ("title",)
|
||||||
# list_filter = ('category',)
|
# list_filter = ('category',)
|
||||||
search_fields = ('description', 'category', )
|
search_fields = (
|
||||||
|
"description",
|
||||||
|
"category",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class MCQuestionAdmin(admin.ModelAdmin):
|
class MCQuestionAdmin(admin.ModelAdmin):
|
||||||
list_display = ('content', )
|
list_display = ("content",)
|
||||||
# list_filter = ('category',)
|
# list_filter = ('category',)
|
||||||
fields = ('content', 'figure', 'quiz', 'explanation', 'choice_order')
|
fields = ("content", "figure", "quiz", "explanation", "choice_order")
|
||||||
|
|
||||||
search_fields = ('content', 'explanation')
|
search_fields = ("content", "explanation")
|
||||||
filter_horizontal = ('quiz',)
|
filter_horizontal = ("quiz",)
|
||||||
|
|
||||||
inlines = [ChoiceInline]
|
inlines = [ChoiceInline]
|
||||||
|
|
||||||
|
|
||||||
class ProgressAdmin(admin.ModelAdmin):
|
class ProgressAdmin(admin.ModelAdmin):
|
||||||
search_fields = ('user', 'score', )
|
search_fields = (
|
||||||
|
"user",
|
||||||
|
"score",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class EssayQuestionAdmin(admin.ModelAdmin):
|
class EssayQuestionAdmin(admin.ModelAdmin):
|
||||||
list_display = ('content', )
|
list_display = ("content",)
|
||||||
# list_filter = ('category',)
|
# list_filter = ('category',)
|
||||||
fields = ('content', 'quiz', 'explanation', )
|
fields = (
|
||||||
search_fields = ('content', 'explanation')
|
"content",
|
||||||
filter_horizontal = ('quiz',)
|
"quiz",
|
||||||
|
"explanation",
|
||||||
|
)
|
||||||
|
search_fields = ("content", "explanation")
|
||||||
|
filter_horizontal = ("quiz",)
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Quiz, QuizAdmin)
|
admin.site.register(Quiz, QuizAdmin)
|
||||||
admin.site.register(MCQuestion, MCQuestionAdmin)
|
admin.site.register(MCQuestion, MCQuestionAdmin)
|
||||||
|
|||||||
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
|
|
||||||
class QuizConfig(AppConfig):
|
class QuizConfig(AppConfig):
|
||||||
name = 'quiz'
|
name = "quiz"
|
||||||
|
|||||||
@ -14,18 +14,20 @@ class QuestionForm(forms.Form):
|
|||||||
def __init__(self, question, *args, **kwargs):
|
def __init__(self, question, *args, **kwargs):
|
||||||
super(QuestionForm, self).__init__(*args, **kwargs)
|
super(QuestionForm, self).__init__(*args, **kwargs)
|
||||||
choice_list = [x for x in question.get_choices_list()]
|
choice_list = [x for x in question.get_choices_list()]
|
||||||
self.fields["answers"] = forms.ChoiceField(choices=choice_list, widget=RadioSelect)
|
self.fields["answers"] = forms.ChoiceField(
|
||||||
|
choices=choice_list, widget=RadioSelect
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class EssayForm(forms.Form):
|
class EssayForm(forms.Form):
|
||||||
def __init__(self, question, *args, **kwargs):
|
def __init__(self, question, *args, **kwargs):
|
||||||
super(EssayForm, self).__init__(*args, **kwargs)
|
super(EssayForm, self).__init__(*args, **kwargs)
|
||||||
self.fields["answers"] = forms.CharField(
|
self.fields["answers"] = forms.CharField(
|
||||||
widget=Textarea(attrs={'style': 'width:100%'}))
|
widget=Textarea(attrs={"style": "width:100%"})
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class QuizAddForm(forms.ModelForm):
|
class QuizAddForm(forms.ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Quiz
|
model = Quiz
|
||||||
exclude = []
|
exclude = []
|
||||||
@ -34,30 +36,35 @@ class QuizAddForm(forms.ModelForm):
|
|||||||
queryset=Question.objects.all().select_subclasses(),
|
queryset=Question.objects.all().select_subclasses(),
|
||||||
required=False,
|
required=False,
|
||||||
label=_("Questions"),
|
label=_("Questions"),
|
||||||
widget=FilteredSelectMultiple(
|
widget=FilteredSelectMultiple(verbose_name=_("Questions"), is_stacked=False),
|
||||||
verbose_name=_("Questions"),
|
)
|
||||||
is_stacked=False))
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(QuizAddForm, self).__init__(*args, **kwargs)
|
super(QuizAddForm, self).__init__(*args, **kwargs)
|
||||||
if self.instance.pk:
|
if self.instance.pk:
|
||||||
self.fields['questions'].initial = self.instance.question_set.all().select_subclasses()
|
self.fields[
|
||||||
|
"questions"
|
||||||
|
].initial = self.instance.question_set.all().select_subclasses()
|
||||||
|
|
||||||
def save(self, commit=True):
|
def save(self, commit=True):
|
||||||
quiz = super(QuizAddForm, self).save(commit=False)
|
quiz = super(QuizAddForm, self).save(commit=False)
|
||||||
quiz.save()
|
quiz.save()
|
||||||
quiz.question_set.set(self.cleaned_data['questions'])
|
quiz.question_set.set(self.cleaned_data["questions"])
|
||||||
self.save_m2m()
|
self.save_m2m()
|
||||||
return quiz
|
return quiz
|
||||||
|
|
||||||
|
|
||||||
class MCQuestionForm(forms.ModelForm):
|
class MCQuestionForm(forms.ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = MCQuestion
|
model = MCQuestion
|
||||||
exclude = ()
|
exclude = ()
|
||||||
|
|
||||||
|
|
||||||
MCQuestionFormSet = inlineformset_factory(
|
MCQuestionFormSet = inlineformset_factory(
|
||||||
MCQuestion, Choice, form=MCQuestionForm, fields=['choice', 'correct'], can_delete=True, extra=5
|
MCQuestion,
|
||||||
|
Choice,
|
||||||
|
form=MCQuestionForm,
|
||||||
|
fields=["choice", "correct"],
|
||||||
|
can_delete=True,
|
||||||
|
extra=5,
|
||||||
)
|
)
|
||||||
|
|||||||
287
quiz/models.py
287
quiz/models.py
@ -4,7 +4,10 @@ import json
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.core.exceptions import ValidationError, ImproperlyConfigured
|
from django.core.exceptions import ValidationError, ImproperlyConfigured
|
||||||
from django.core.validators import (MaxValueValidator, validate_comma_separated_integer_list,)
|
from django.core.validators import (
|
||||||
|
MaxValueValidator,
|
||||||
|
validate_comma_separated_integer_list,
|
||||||
|
)
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -17,15 +20,15 @@ from course.models import Course
|
|||||||
from .utils import *
|
from .utils import *
|
||||||
|
|
||||||
CHOICE_ORDER_OPTIONS = (
|
CHOICE_ORDER_OPTIONS = (
|
||||||
('content', _('Content')),
|
("content", _("Content")),
|
||||||
('random', _('Random')),
|
("random", _("Random")),
|
||||||
('none', _('None'))
|
("none", _("None")),
|
||||||
)
|
)
|
||||||
|
|
||||||
CATEGORY_OPTIONS = (
|
CATEGORY_OPTIONS = (
|
||||||
('assignment', _('Assignment')),
|
("assignment", _("Assignment")),
|
||||||
('exam', _('Exam')),
|
("exam", _("Exam")),
|
||||||
('practice', _('Practice Quiz'))
|
("practice", _("Practice Quiz")),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -33,12 +36,15 @@ class QuizManager(models.Manager):
|
|||||||
def search(self, query=None):
|
def search(self, query=None):
|
||||||
qs = self.get_queryset()
|
qs = self.get_queryset()
|
||||||
if query is not None:
|
if query is not None:
|
||||||
or_lookup = (Q(title__icontains=query) |
|
or_lookup = (
|
||||||
Q(description__icontains=query)|
|
Q(title__icontains=query)
|
||||||
Q(category__icontains=query)|
|
| Q(description__icontains=query)
|
||||||
Q(slug__icontains=query)
|
| Q(category__icontains=query)
|
||||||
|
| Q(slug__icontains=query)
|
||||||
)
|
)
|
||||||
qs = qs.filter(or_lookup).distinct() # distinct() is often necessary with Q lookups
|
qs = qs.filter(
|
||||||
|
or_lookup
|
||||||
|
).distinct() # distinct() is often necessary with Q lookups
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
@ -46,42 +52,76 @@ class Quiz(models.Model):
|
|||||||
course = models.ForeignKey(Course, on_delete=models.CASCADE, null=True)
|
course = models.ForeignKey(Course, on_delete=models.CASCADE, null=True)
|
||||||
title = models.CharField(verbose_name=_("Title"), max_length=60, blank=False)
|
title = models.CharField(verbose_name=_("Title"), max_length=60, blank=False)
|
||||||
slug = models.SlugField(blank=True, unique=True)
|
slug = models.SlugField(blank=True, unique=True)
|
||||||
description = models.TextField(verbose_name=_("Description"), blank=True, help_text=_("a description of the quiz"))
|
description = models.TextField(
|
||||||
|
verbose_name=_("Description"),
|
||||||
|
blank=True,
|
||||||
|
help_text=_("a description of the quiz"),
|
||||||
|
)
|
||||||
category = models.TextField(choices=CATEGORY_OPTIONS, blank=True)
|
category = models.TextField(choices=CATEGORY_OPTIONS, blank=True)
|
||||||
random_order = models.BooleanField(blank=False, default=False, verbose_name=_("Random Order"),
|
random_order = models.BooleanField(
|
||||||
help_text=_("Display the questions in a random order or as they are set?"))
|
blank=False,
|
||||||
|
default=False,
|
||||||
|
verbose_name=_("Random Order"),
|
||||||
|
help_text=_("Display the questions in a random order or as they are set?"),
|
||||||
|
)
|
||||||
|
|
||||||
# max_questions = models.PositiveIntegerField(blank=True, null=True, verbose_name=_("Max Questions"),
|
# max_questions = models.PositiveIntegerField(blank=True, null=True, verbose_name=_("Max Questions"),
|
||||||
# help_text=_("Number of questions to be answered on each attempt."))
|
# help_text=_("Number of questions to be answered on each attempt."))
|
||||||
|
|
||||||
answers_at_end = models.BooleanField(blank=False, default=False, verbose_name=_("Answers at end"),
|
answers_at_end = models.BooleanField(
|
||||||
help_text=_("Correct answer is NOT shown after question. Answers displayed at the end."))
|
blank=False,
|
||||||
|
default=False,
|
||||||
|
verbose_name=_("Answers at end"),
|
||||||
|
help_text=_(
|
||||||
|
"Correct answer is NOT shown after question. Answers displayed at the end."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
exam_paper = models.BooleanField(blank=False, default=False, verbose_name=_("Exam Paper"),
|
exam_paper = models.BooleanField(
|
||||||
help_text=_("If yes, the result of each attempt by a user will be stored. Necessary for marking."))
|
blank=False,
|
||||||
|
default=False,
|
||||||
|
verbose_name=_("Exam Paper"),
|
||||||
|
help_text=_(
|
||||||
|
"If yes, the result of each attempt by a user will be stored. Necessary for marking."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
single_attempt = models.BooleanField(blank=False, default=False, verbose_name=_("Single Attempt"),
|
single_attempt = models.BooleanField(
|
||||||
help_text=_("If yes, only one attempt by a user will be permitted."))
|
blank=False,
|
||||||
|
default=False,
|
||||||
|
verbose_name=_("Single Attempt"),
|
||||||
|
help_text=_("If yes, only one attempt by a user will be permitted."),
|
||||||
|
)
|
||||||
|
|
||||||
pass_mark = models.SmallIntegerField(blank=True, default=50, verbose_name=_("Pass Mark"), validators=[MaxValueValidator(100)],
|
pass_mark = models.SmallIntegerField(
|
||||||
help_text=_("Percentage required to pass exam."))
|
blank=True,
|
||||||
|
default=50,
|
||||||
|
verbose_name=_("Pass Mark"),
|
||||||
|
validators=[MaxValueValidator(100)],
|
||||||
|
help_text=_("Percentage required to pass exam."),
|
||||||
|
)
|
||||||
|
|
||||||
draft = models.BooleanField(blank=True, default=False, verbose_name=_("Draft"),
|
draft = models.BooleanField(
|
||||||
help_text=_("If yes, the quiz is not displayed in the quiz list and can only be taken by users who can edit quizzes."))
|
blank=True,
|
||||||
|
default=False,
|
||||||
|
verbose_name=_("Draft"),
|
||||||
|
help_text=_(
|
||||||
|
"If yes, the quiz is not displayed in the quiz list and can only be taken by users who can edit quizzes."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
timestamp = models.DateTimeField(auto_now=True)
|
timestamp = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
objects = QuizManager()
|
objects = QuizManager()
|
||||||
|
|
||||||
def save(self, force_insert=False, force_update=False, *args, **kwargs):
|
def save(self, force_insert=False, force_update=False, *args, **kwargs):
|
||||||
|
|
||||||
if self.single_attempt is True:
|
if self.single_attempt is True:
|
||||||
self.exam_paper = True
|
self.exam_paper = True
|
||||||
|
|
||||||
if self.pass_mark > 100:
|
if self.pass_mark > 100:
|
||||||
raise ValidationError('%s is above 100' % self.pass_mark)
|
raise ValidationError("%s is above 100" % self.pass_mark)
|
||||||
if self.pass_mark < 0:
|
if self.pass_mark < 0:
|
||||||
raise ValidationError('%s is below 0' % self.pass_mark)
|
raise ValidationError("%s is below 0" % self.pass_mark)
|
||||||
|
|
||||||
super(Quiz, self).save(force_insert, force_update, *args, **kwargs)
|
super(Quiz, self).save(force_insert, force_update, *args, **kwargs)
|
||||||
|
|
||||||
@ -101,18 +141,18 @@ class Quiz(models.Model):
|
|||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
# return reverse('quiz_start_page', kwargs={'pk': self.pk})
|
# return reverse('quiz_start_page', kwargs={'pk': self.pk})
|
||||||
return reverse('quiz_index', kwargs={'slug': self.course.slug})
|
return reverse("quiz_index", kwargs={"slug": self.course.slug})
|
||||||
|
|
||||||
|
|
||||||
def quiz_pre_save_receiver(sender, instance, *args, **kwargs):
|
def quiz_pre_save_receiver(sender, instance, *args, **kwargs):
|
||||||
if not instance.slug:
|
if not instance.slug:
|
||||||
instance.slug = unique_slug_generator(instance)
|
instance.slug = unique_slug_generator(instance)
|
||||||
|
|
||||||
|
|
||||||
pre_save.connect(quiz_pre_save_receiver, sender=Quiz)
|
pre_save.connect(quiz_pre_save_receiver, sender=Quiz)
|
||||||
|
|
||||||
|
|
||||||
class ProgressManager(models.Manager):
|
class ProgressManager(models.Manager):
|
||||||
|
|
||||||
def new_progress(self, user):
|
def new_progress(self, user):
|
||||||
new_progress = self.create(user=user, score="")
|
new_progress = self.create(user=user, score="")
|
||||||
new_progress.save()
|
new_progress.save()
|
||||||
@ -120,8 +160,14 @@ class ProgressManager(models.Manager):
|
|||||||
|
|
||||||
|
|
||||||
class Progress(models.Model):
|
class Progress(models.Model):
|
||||||
user = models.OneToOneField(settings.AUTH_USER_MODEL, verbose_name=_("User"), on_delete=models.CASCADE)
|
user = models.OneToOneField(
|
||||||
score = models.CharField(max_length=1024, verbose_name=_("Score"), validators=[validate_comma_separated_integer_list])
|
settings.AUTH_USER_MODEL, verbose_name=_("User"), on_delete=models.CASCADE
|
||||||
|
)
|
||||||
|
score = models.CharField(
|
||||||
|
max_length=1024,
|
||||||
|
verbose_name=_("Score"),
|
||||||
|
validators=[validate_comma_separated_integer_list],
|
||||||
|
)
|
||||||
|
|
||||||
objects = ProgressManager()
|
objects = ProgressManager()
|
||||||
|
|
||||||
@ -143,7 +189,17 @@ class Progress(models.Model):
|
|||||||
def update_score(self, question, score_to_add=0, possible_to_add=0):
|
def update_score(self, question, score_to_add=0, possible_to_add=0):
|
||||||
# category_test = Category.objects.filter(category=question.category).exists()
|
# category_test = Category.objects.filter(category=question.category).exists()
|
||||||
|
|
||||||
if any([item is False for item in [score_to_add, possible_to_add, isinstance(score_to_add, int), isinstance(possible_to_add, int)]]):
|
if any(
|
||||||
|
[
|
||||||
|
item is False
|
||||||
|
for item in [
|
||||||
|
score_to_add,
|
||||||
|
possible_to_add,
|
||||||
|
isinstance(score_to_add, int),
|
||||||
|
isinstance(possible_to_add, int),
|
||||||
|
]
|
||||||
|
]
|
||||||
|
):
|
||||||
return _("error"), _("category does not exist or invalid score")
|
return _("error"), _("category does not exist or invalid score")
|
||||||
|
|
||||||
to_find = re.escape(str(question.quiz)) + r",(?P<score>\d+),(?P<possible>\d+),"
|
to_find = re.escape(str(question.quiz)) + r",(?P<score>\d+),(?P<possible>\d+),"
|
||||||
@ -151,10 +207,12 @@ class Progress(models.Model):
|
|||||||
match = re.search(to_find, self.score, re.IGNORECASE)
|
match = re.search(to_find, self.score, re.IGNORECASE)
|
||||||
|
|
||||||
if match:
|
if match:
|
||||||
updated_score = int(match.group('score')) + abs(score_to_add)
|
updated_score = int(match.group("score")) + abs(score_to_add)
|
||||||
updated_possible = int(match.group('possible')) + abs(possible_to_add)
|
updated_possible = int(match.group("possible")) + abs(possible_to_add)
|
||||||
|
|
||||||
new_score = ",".join([str(question.quiz), str(updated_score), str(updated_possible), ""])
|
new_score = ",".join(
|
||||||
|
[str(question.quiz), str(updated_score), str(updated_possible), ""]
|
||||||
|
)
|
||||||
|
|
||||||
# swap old score for the new one
|
# swap old score for the new one
|
||||||
self.score = self.score.replace(match.group(), new_score)
|
self.score = self.score.replace(match.group(), new_score)
|
||||||
@ -162,28 +220,33 @@ class Progress(models.Model):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
# if not present but existing, add with the points passed in
|
# if not present but existing, add with the points passed in
|
||||||
self.score += ",".join([str(question.quiz), str(score_to_add), str(possible_to_add), ""])
|
self.score += ",".join(
|
||||||
|
[str(question.quiz), str(score_to_add), str(possible_to_add), ""]
|
||||||
|
)
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def show_exams(self):
|
def show_exams(self):
|
||||||
if self.user.is_superuser:
|
if self.user.is_superuser:
|
||||||
return Sitting.objects.filter(complete=True).order_by('-end')
|
return Sitting.objects.filter(complete=True).order_by("-end")
|
||||||
else:
|
else:
|
||||||
return Sitting.objects.filter(user=self.user, complete=True).order_by('-end')
|
return Sitting.objects.filter(user=self.user, complete=True).order_by(
|
||||||
|
"-end"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SittingManager(models.Manager):
|
class SittingManager(models.Manager):
|
||||||
|
|
||||||
def new_sitting(self, user, quiz, course):
|
def new_sitting(self, user, quiz, course):
|
||||||
if quiz.random_order is True:
|
if quiz.random_order is True:
|
||||||
question_set = quiz.question_set.all().select_subclasses().order_by('?')
|
question_set = quiz.question_set.all().select_subclasses().order_by("?")
|
||||||
else:
|
else:
|
||||||
question_set = quiz.question_set.all().select_subclasses()
|
question_set = quiz.question_set.all().select_subclasses()
|
||||||
|
|
||||||
question_set = [item.id for item in question_set]
|
question_set = [item.id for item in question_set]
|
||||||
|
|
||||||
if len(question_set) == 0:
|
if len(question_set) == 0:
|
||||||
raise ImproperlyConfigured('Question set of the quiz is empty. Please configure questions properly')
|
raise ImproperlyConfigured(
|
||||||
|
"Question set of the quiz is empty. Please configure questions properly"
|
||||||
|
)
|
||||||
|
|
||||||
# if quiz.max_questions and quiz.max_questions < len(question_set):
|
# if quiz.max_questions and quiz.max_questions < len(question_set):
|
||||||
# question_set = question_set[:quiz.max_questions]
|
# question_set = question_set[:quiz.max_questions]
|
||||||
@ -191,43 +254,70 @@ class SittingManager(models.Manager):
|
|||||||
questions = ",".join(map(str, question_set)) + ","
|
questions = ",".join(map(str, question_set)) + ","
|
||||||
|
|
||||||
new_sitting = self.create(
|
new_sitting = self.create(
|
||||||
user=user, quiz=quiz, course=course, question_order=questions,
|
user=user,
|
||||||
question_list=questions, incorrect_questions="",
|
quiz=quiz,
|
||||||
|
course=course,
|
||||||
|
question_order=questions,
|
||||||
|
question_list=questions,
|
||||||
|
incorrect_questions="",
|
||||||
current_score=0,
|
current_score=0,
|
||||||
complete=False,
|
complete=False,
|
||||||
user_answers='{}'
|
user_answers="{}",
|
||||||
)
|
)
|
||||||
return new_sitting
|
return new_sitting
|
||||||
|
|
||||||
def user_sitting(self, user, quiz, course):
|
def user_sitting(self, user, quiz, course):
|
||||||
if quiz.single_attempt is True and self.filter(user=user, quiz=quiz, course=course, complete=True).exists():
|
if (
|
||||||
|
quiz.single_attempt is True
|
||||||
|
and self.filter(user=user, quiz=quiz, course=course, complete=True).exists()
|
||||||
|
):
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
sitting = self.get(user=user, quiz=quiz, course=course, complete=False)
|
sitting = self.get(user=user, quiz=quiz, course=course, complete=False)
|
||||||
except Sitting.DoesNotExist:
|
except Sitting.DoesNotExist:
|
||||||
sitting = self.new_sitting(user, quiz, course)
|
sitting = self.new_sitting(user, quiz, course)
|
||||||
except Sitting.MultipleObjectsReturned:
|
except Sitting.MultipleObjectsReturned:
|
||||||
sitting = self.filter(user=user, quiz=quiz, course=course, complete=False)[0]
|
sitting = self.filter(user=user, quiz=quiz, course=course, complete=False)[
|
||||||
|
0
|
||||||
|
]
|
||||||
return sitting
|
return sitting
|
||||||
|
|
||||||
|
|
||||||
class Sitting(models.Model):
|
class Sitting(models.Model):
|
||||||
user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_("User"), on_delete=models.CASCADE)
|
user = models.ForeignKey(
|
||||||
|
settings.AUTH_USER_MODEL, verbose_name=_("User"), on_delete=models.CASCADE
|
||||||
|
)
|
||||||
quiz = models.ForeignKey(Quiz, verbose_name=_("Quiz"), on_delete=models.CASCADE)
|
quiz = models.ForeignKey(Quiz, verbose_name=_("Quiz"), on_delete=models.CASCADE)
|
||||||
course = models.ForeignKey(Course, null=True, verbose_name=_("Course"), on_delete=models.CASCADE)
|
course = models.ForeignKey(
|
||||||
|
Course, null=True, verbose_name=_("Course"), on_delete=models.CASCADE
|
||||||
|
)
|
||||||
|
|
||||||
question_order = models.CharField(max_length=1024, verbose_name=_("Question Order"),
|
question_order = models.CharField(
|
||||||
validators=[validate_comma_separated_integer_list])
|
max_length=1024,
|
||||||
|
verbose_name=_("Question Order"),
|
||||||
|
validators=[validate_comma_separated_integer_list],
|
||||||
|
)
|
||||||
|
|
||||||
question_list = models.CharField(max_length=1024, verbose_name=_("Question List"),
|
question_list = models.CharField(
|
||||||
validators=[validate_comma_separated_integer_list])
|
max_length=1024,
|
||||||
|
verbose_name=_("Question List"),
|
||||||
|
validators=[validate_comma_separated_integer_list],
|
||||||
|
)
|
||||||
|
|
||||||
incorrect_questions = models.CharField(max_length=1024, blank=True, verbose_name=_("Incorrect questions"),
|
incorrect_questions = models.CharField(
|
||||||
validators=[validate_comma_separated_integer_list])
|
max_length=1024,
|
||||||
|
blank=True,
|
||||||
|
verbose_name=_("Incorrect questions"),
|
||||||
|
validators=[validate_comma_separated_integer_list],
|
||||||
|
)
|
||||||
|
|
||||||
current_score = models.IntegerField(verbose_name=_("Current Score"))
|
current_score = models.IntegerField(verbose_name=_("Current Score"))
|
||||||
complete = models.BooleanField(default=False, blank=False, verbose_name=_("Complete"))
|
complete = models.BooleanField(
|
||||||
user_answers = models.TextField(blank=True, default='{}', verbose_name=_("User Answers"))
|
default=False, blank=False, verbose_name=_("Complete")
|
||||||
|
)
|
||||||
|
user_answers = models.TextField(
|
||||||
|
blank=True, default="{}", verbose_name=_("User Answers")
|
||||||
|
)
|
||||||
start = models.DateTimeField(auto_now_add=True, verbose_name=_("Start"))
|
start = models.DateTimeField(auto_now_add=True, verbose_name=_("Start"))
|
||||||
end = models.DateTimeField(null=True, blank=True, verbose_name=_("End"))
|
end = models.DateTimeField(null=True, blank=True, verbose_name=_("End"))
|
||||||
|
|
||||||
@ -240,7 +330,7 @@ class Sitting(models.Model):
|
|||||||
if not self.question_list:
|
if not self.question_list:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
first, _ = self.question_list.split(',', 1)
|
first, _ = self.question_list.split(",", 1)
|
||||||
question_id = int(first)
|
question_id = int(first)
|
||||||
return Question.objects.get_subclass(id=question_id)
|
return Question.objects.get_subclass(id=question_id)
|
||||||
|
|
||||||
@ -248,7 +338,7 @@ class Sitting(models.Model):
|
|||||||
if not self.question_list:
|
if not self.question_list:
|
||||||
return
|
return
|
||||||
|
|
||||||
_, others = self.question_list.split(',', 1)
|
_, others = self.question_list.split(",", 1)
|
||||||
self.question_list = others
|
self.question_list = others
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
@ -261,7 +351,7 @@ class Sitting(models.Model):
|
|||||||
return self.current_score
|
return self.current_score
|
||||||
|
|
||||||
def _question_ids(self):
|
def _question_ids(self):
|
||||||
return [int(n) for n in self.question_order.split(',') if n]
|
return [int(n) for n in self.question_order.split(",") if n]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def get_percent_correct(self):
|
def get_percent_correct(self):
|
||||||
@ -287,7 +377,7 @@ class Sitting(models.Model):
|
|||||||
|
|
||||||
def add_incorrect_question(self, question):
|
def add_incorrect_question(self, question):
|
||||||
if len(self.incorrect_questions) > 0:
|
if len(self.incorrect_questions) > 0:
|
||||||
self.incorrect_questions += ','
|
self.incorrect_questions += ","
|
||||||
self.incorrect_questions += str(question.id) + ","
|
self.incorrect_questions += str(question.id) + ","
|
||||||
if self.complete:
|
if self.complete:
|
||||||
self.add_to_score(-1)
|
self.add_to_score(-1)
|
||||||
@ -295,12 +385,12 @@ class Sitting(models.Model):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def get_incorrect_questions(self):
|
def get_incorrect_questions(self):
|
||||||
return [int(q) for q in self.incorrect_questions.split(',') if q]
|
return [int(q) for q in self.incorrect_questions.split(",") if q]
|
||||||
|
|
||||||
def remove_incorrect_question(self, question):
|
def remove_incorrect_question(self, question):
|
||||||
current = self.get_incorrect_questions
|
current = self.get_incorrect_questions
|
||||||
current.remove(question.id)
|
current.remove(question.id)
|
||||||
self.incorrect_questions = ','.join(map(str, current))
|
self.incorrect_questions = ",".join(map(str, current))
|
||||||
self.add_to_score(1)
|
self.add_to_score(1)
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
@ -323,7 +413,10 @@ class Sitting(models.Model):
|
|||||||
|
|
||||||
def get_questions(self, with_answers=False):
|
def get_questions(self, with_answers=False):
|
||||||
question_ids = self._question_ids()
|
question_ids = self._question_ids()
|
||||||
questions = sorted(self.quiz.question_set.filter(id__in=question_ids).select_subclasses(), key=lambda q: question_ids.index(q.id))
|
questions = sorted(
|
||||||
|
self.quiz.question_set.filter(id__in=question_ids).select_subclasses(),
|
||||||
|
key=lambda q: question_ids.index(q.id),
|
||||||
|
)
|
||||||
|
|
||||||
if with_answers:
|
if with_answers:
|
||||||
user_answers = json.loads(self.user_answers)
|
user_answers = json.loads(self.user_answers)
|
||||||
@ -348,12 +441,21 @@ class Sitting(models.Model):
|
|||||||
|
|
||||||
class Question(models.Model):
|
class Question(models.Model):
|
||||||
quiz = models.ManyToManyField(Quiz, verbose_name=_("Quiz"), blank=True)
|
quiz = models.ManyToManyField(Quiz, verbose_name=_("Quiz"), blank=True)
|
||||||
figure = models.ImageField(upload_to='uploads/%Y/%m/%d', blank=True, null=True, verbose_name=_("Figure"))
|
figure = models.ImageField(
|
||||||
content = models.CharField(max_length=1000, blank=False,
|
upload_to="uploads/%Y/%m/%d", blank=True, null=True, verbose_name=_("Figure")
|
||||||
help_text=_("Enter the question text that you want displayed"), verbose_name=_('Question'))
|
)
|
||||||
explanation = models.TextField(max_length=2000, blank=True,
|
content = models.CharField(
|
||||||
|
max_length=1000,
|
||||||
|
blank=False,
|
||||||
|
help_text=_("Enter the question text that you want displayed"),
|
||||||
|
verbose_name=_("Question"),
|
||||||
|
)
|
||||||
|
explanation = models.TextField(
|
||||||
|
max_length=2000,
|
||||||
|
blank=True,
|
||||||
help_text=_("Explanation to be shown after the question has been answered."),
|
help_text=_("Explanation to be shown after the question has been answered."),
|
||||||
verbose_name=_('Explanation'))
|
verbose_name=_("Explanation"),
|
||||||
|
)
|
||||||
|
|
||||||
objects = InheritanceManager()
|
objects = InheritanceManager()
|
||||||
|
|
||||||
@ -366,12 +468,16 @@ class Question(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
class MCQuestion(Question):
|
class MCQuestion(Question):
|
||||||
|
|
||||||
choice_order = models.CharField(
|
choice_order = models.CharField(
|
||||||
max_length=30, null=True, blank=True,
|
max_length=30,
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
choices=CHOICE_ORDER_OPTIONS,
|
choices=CHOICE_ORDER_OPTIONS,
|
||||||
help_text=_("The order in which multichoice choice options are displayed to the user"),
|
help_text=_(
|
||||||
verbose_name=_("Choice Order"))
|
"The order in which multichoice choice options are displayed to the user"
|
||||||
|
),
|
||||||
|
verbose_name=_("Choice Order"),
|
||||||
|
)
|
||||||
|
|
||||||
def check_if_correct(self, guess):
|
def check_if_correct(self, guess):
|
||||||
answer = Choice.objects.get(id=guess)
|
answer = Choice.objects.get(id=guess)
|
||||||
@ -382,11 +488,11 @@ class MCQuestion(Question):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def order_choices(self, queryset):
|
def order_choices(self, queryset):
|
||||||
if self.choice_order == 'content':
|
if self.choice_order == "content":
|
||||||
return queryset.order_by('choice')
|
return queryset.order_by("choice")
|
||||||
if self.choice_order == 'random':
|
if self.choice_order == "random":
|
||||||
return queryset.order_by('?')
|
return queryset.order_by("?")
|
||||||
if self.choice_order == 'none':
|
if self.choice_order == "none":
|
||||||
return queryset.order_by()
|
return queryset.order_by()
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
@ -394,8 +500,10 @@ class MCQuestion(Question):
|
|||||||
return self.order_choices(Choice.objects.filter(question=self))
|
return self.order_choices(Choice.objects.filter(question=self))
|
||||||
|
|
||||||
def get_choices_list(self):
|
def get_choices_list(self):
|
||||||
return [(choice.id, choice.choice) for choice in
|
return [
|
||||||
self.order_choices(Choice.objects.filter(question=self))]
|
(choice.id, choice.choice)
|
||||||
|
for choice in self.order_choices(Choice.objects.filter(question=self))
|
||||||
|
]
|
||||||
|
|
||||||
def answer_choice_to_string(self, guess):
|
def answer_choice_to_string(self, guess):
|
||||||
return Choice.objects.get(id=guess).choice
|
return Choice.objects.get(id=guess).choice
|
||||||
@ -406,15 +514,23 @@ class MCQuestion(Question):
|
|||||||
|
|
||||||
|
|
||||||
class Choice(models.Model):
|
class Choice(models.Model):
|
||||||
question = models.ForeignKey(MCQuestion, verbose_name=_("Question"), on_delete=models.CASCADE)
|
question = models.ForeignKey(
|
||||||
|
MCQuestion, verbose_name=_("Question"), on_delete=models.CASCADE
|
||||||
|
)
|
||||||
|
|
||||||
choice = models.CharField(max_length=1000, blank=False,
|
choice = models.CharField(
|
||||||
|
max_length=1000,
|
||||||
|
blank=False,
|
||||||
help_text=_("Enter the choice text that you want displayed"),
|
help_text=_("Enter the choice text that you want displayed"),
|
||||||
verbose_name=_("Content"))
|
verbose_name=_("Content"),
|
||||||
|
)
|
||||||
|
|
||||||
correct = models.BooleanField(blank=False, default=False,
|
correct = models.BooleanField(
|
||||||
|
blank=False,
|
||||||
|
default=False,
|
||||||
help_text=_("Is this a correct answer?"),
|
help_text=_("Is this a correct answer?"),
|
||||||
verbose_name=_("Correct"))
|
verbose_name=_("Correct"),
|
||||||
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.choice
|
return self.choice
|
||||||
@ -425,7 +541,6 @@ class Choice(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
class Essay_Question(Question):
|
class Essay_Question(Question):
|
||||||
|
|
||||||
def check_if_correct(self, guess):
|
def check_if_correct(self, guess):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|||||||
32
quiz/urls.py
32
quiz/urls.py
@ -2,21 +2,23 @@ from django.urls import path
|
|||||||
from .views import *
|
from .views import *
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
path("<slug>/quizzes/", quiz_list, name="quiz_index"),
|
||||||
path('<slug>/quizzes/', quiz_list, name='quiz_index'),
|
path("progress/", view=QuizUserProgressView.as_view(), name="quiz_progress"),
|
||||||
|
|
||||||
path('progress/', view=QuizUserProgressView.as_view(), name='quiz_progress'),
|
|
||||||
|
|
||||||
# path('marking/<int:pk>/', view=QuizMarkingList.as_view(), name='quiz_marking'),
|
# path('marking/<int:pk>/', view=QuizMarkingList.as_view(), name='quiz_marking'),
|
||||||
path('marking_list/', view=QuizMarkingList.as_view(), name='quiz_marking'),
|
path("marking_list/", view=QuizMarkingList.as_view(), name="quiz_marking"),
|
||||||
|
path(
|
||||||
path('marking/<int:pk>/', view=QuizMarkingDetail.as_view(), name='quiz_marking_detail'),
|
"marking/<int:pk>/",
|
||||||
|
view=QuizMarkingDetail.as_view(),
|
||||||
path('<int:pk>/<slug>/take/', view=QuizTake.as_view(), name='quiz_take'),
|
name="quiz_marking_detail",
|
||||||
|
),
|
||||||
path('<slug>/quiz_add/', QuizCreateView.as_view(), name='quiz_create'),
|
path("<int:pk>/<slug>/take/", view=QuizTake.as_view(), name="quiz_take"),
|
||||||
path('<slug>/<int:pk>/add/', QuizUpdateView.as_view(), name='quiz_update'),
|
path("<slug>/quiz_add/", QuizCreateView.as_view(), name="quiz_create"),
|
||||||
path('<slug>/<int:pk>/delete/', quiz_delete, name='quiz_delete'),
|
path("<slug>/<int:pk>/add/", QuizUpdateView.as_view(), name="quiz_update"),
|
||||||
path('mc-question/add/<slug>/<int:quiz_id>/', MCQuestionCreate.as_view(), name='mc_create'),
|
path("<slug>/<int:pk>/delete/", quiz_delete, name="quiz_delete"),
|
||||||
|
path(
|
||||||
|
"mc-question/add/<slug>/<int:quiz_id>/",
|
||||||
|
MCQuestionCreate.as_view(),
|
||||||
|
name="mc_create",
|
||||||
|
),
|
||||||
# path('mc-question/add/<int:pk>/<quiz_pk>/', MCQuestionCreate.as_view(), name='mc_create'),
|
# path('mc-question/add/<int:pk>/<quiz_pk>/', MCQuestionCreate.as_view(), name='mc_create'),
|
||||||
]
|
]
|
||||||
|
|||||||
@ -7,7 +7,7 @@ from django.utils.text import slugify
|
|||||||
|
|
||||||
|
|
||||||
def random_string_generator(size=10, chars=string.ascii_lowercase + string.digits):
|
def random_string_generator(size=10, chars=string.ascii_lowercase + string.digits):
|
||||||
return ''.join(random.choice(chars) for _ in range(size))
|
return "".join(random.choice(chars) for _ in range(size))
|
||||||
|
|
||||||
|
|
||||||
def unique_slug_generator(instance, new_slug=None):
|
def unique_slug_generator(instance, new_slug=None):
|
||||||
@ -24,8 +24,7 @@ def unique_slug_generator(instance, new_slug=None):
|
|||||||
qs_exists = Klass.objects.filter(slug=slug).exists()
|
qs_exists = Klass.objects.filter(slug=slug).exists()
|
||||||
if qs_exists:
|
if qs_exists:
|
||||||
new_slug = "{slug}-{randstr}".format(
|
new_slug = "{slug}-{randstr}".format(
|
||||||
slug=slug,
|
slug=slug, randstr=random_string_generator(size=4)
|
||||||
randstr=random_string_generator(size=4)
|
|
||||||
)
|
)
|
||||||
return unique_slug_generator(instance, new_slug=new_slug)
|
return unique_slug_generator(instance, new_slug=new_slug)
|
||||||
return slug
|
return slug
|
||||||
|
|||||||
202
quiz/views.py
202
quiz/views.py
@ -4,7 +4,16 @@ from django.contrib.auth.decorators import login_required, permission_required
|
|||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.shortcuts import get_object_or_404, render, redirect
|
from django.shortcuts import get_object_or_404, render, redirect
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
from django.views.generic import DetailView, ListView, TemplateView, FormView, CreateView, FormView, DeleteView, UpdateView
|
from django.views.generic import (
|
||||||
|
DetailView,
|
||||||
|
ListView,
|
||||||
|
TemplateView,
|
||||||
|
FormView,
|
||||||
|
CreateView,
|
||||||
|
FormView,
|
||||||
|
DeleteView,
|
||||||
|
UpdateView,
|
||||||
|
)
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
@ -16,58 +25,62 @@ from .models import *
|
|||||||
from .forms import *
|
from .forms import *
|
||||||
|
|
||||||
|
|
||||||
@method_decorator([login_required, lecturer_required], name='dispatch')
|
@method_decorator([login_required, lecturer_required], name="dispatch")
|
||||||
class QuizCreateView(CreateView):
|
class QuizCreateView(CreateView):
|
||||||
model = Quiz
|
model = Quiz
|
||||||
form_class = QuizAddForm
|
form_class = QuizAddForm
|
||||||
|
|
||||||
def get_context_data(self, *args, **kwargs):
|
def get_context_data(self, *args, **kwargs):
|
||||||
context = super(QuizCreateView, self).get_context_data(**kwargs)
|
context = super(QuizCreateView, self).get_context_data(**kwargs)
|
||||||
context['course'] = Course.objects.get(slug=self.kwargs['slug'])
|
context["course"] = Course.objects.get(slug=self.kwargs["slug"])
|
||||||
if self.request.POST:
|
if self.request.POST:
|
||||||
context['form'] = QuizAddForm(self.request.POST)
|
context["form"] = QuizAddForm(self.request.POST)
|
||||||
# context['quiz'] = self.request.POST.get('quiz')
|
# context['quiz'] = self.request.POST.get('quiz')
|
||||||
else:
|
else:
|
||||||
context['form'] = QuizAddForm(initial={'course': Course.objects.get(slug=self.kwargs['slug'])})
|
context["form"] = QuizAddForm(
|
||||||
|
initial={"course": Course.objects.get(slug=self.kwargs["slug"])}
|
||||||
|
)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def form_valid(self, form, **kwargs):
|
def form_valid(self, form, **kwargs):
|
||||||
context = self.get_context_data()
|
context = self.get_context_data()
|
||||||
form = context['form']
|
form = context["form"]
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
self.object = form.save()
|
self.object = form.save()
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.instance = self.object
|
form.instance = self.object
|
||||||
form.save()
|
form.save()
|
||||||
return redirect('mc_create', slug=self.kwargs['slug'], quiz_id=form.instance.id)
|
return redirect(
|
||||||
|
"mc_create", slug=self.kwargs["slug"], quiz_id=form.instance.id
|
||||||
|
)
|
||||||
return super(QuizCreateView, self).form_invalid(form)
|
return super(QuizCreateView, self).form_invalid(form)
|
||||||
|
|
||||||
|
|
||||||
@method_decorator([login_required, lecturer_required], name='dispatch')
|
@method_decorator([login_required, lecturer_required], name="dispatch")
|
||||||
class QuizUpdateView(UpdateView):
|
class QuizUpdateView(UpdateView):
|
||||||
model = Quiz
|
model = Quiz
|
||||||
form_class = QuizAddForm
|
form_class = QuizAddForm
|
||||||
|
|
||||||
def get_context_data(self, *args, **kwargs):
|
def get_context_data(self, *args, **kwargs):
|
||||||
context = super(QuizUpdateView, self).get_context_data(**kwargs)
|
context = super(QuizUpdateView, self).get_context_data(**kwargs)
|
||||||
context['course'] = Course.objects.get(slug=self.kwargs['slug'])
|
context["course"] = Course.objects.get(slug=self.kwargs["slug"])
|
||||||
quiz = Quiz.objects.get(pk=self.kwargs['pk'])
|
quiz = Quiz.objects.get(pk=self.kwargs["pk"])
|
||||||
if self.request.POST:
|
if self.request.POST:
|
||||||
context['form'] = QuizAddForm(self.request.POST, instance=quiz)
|
context["form"] = QuizAddForm(self.request.POST, instance=quiz)
|
||||||
else:
|
else:
|
||||||
context['form'] = QuizAddForm(instance=quiz)
|
context["form"] = QuizAddForm(instance=quiz)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def form_valid(self, form, **kwargs):
|
def form_valid(self, form, **kwargs):
|
||||||
context = self.get_context_data()
|
context = self.get_context_data()
|
||||||
course = context['course']
|
course = context["course"]
|
||||||
form = context['form']
|
form = context["form"]
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
self.object = form.save()
|
self.object = form.save()
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
form.instance = self.object
|
form.instance = self.object
|
||||||
form.save()
|
form.save()
|
||||||
return redirect('quiz_index', course.slug)
|
return redirect("quiz_index", course.slug)
|
||||||
return super(QuizUpdateView, self).form_invalid(form)
|
return super(QuizUpdateView, self).form_invalid(form)
|
||||||
|
|
||||||
|
|
||||||
@ -77,54 +90,62 @@ def quiz_delete(request, slug, pk):
|
|||||||
quiz = Quiz.objects.get(pk=pk)
|
quiz = Quiz.objects.get(pk=pk)
|
||||||
course = Course.objects.get(slug=slug)
|
course = Course.objects.get(slug=slug)
|
||||||
quiz.delete()
|
quiz.delete()
|
||||||
messages.success(request, f'successfuly deleted.')
|
messages.success(request, f"successfuly deleted.")
|
||||||
return redirect('quiz_index', quiz.course.slug)
|
return redirect("quiz_index", quiz.course.slug)
|
||||||
|
|
||||||
|
|
||||||
@method_decorator([login_required, lecturer_required], name='dispatch')
|
@method_decorator([login_required, lecturer_required], name="dispatch")
|
||||||
class MCQuestionCreate(CreateView):
|
class MCQuestionCreate(CreateView):
|
||||||
model = MCQuestion
|
model = MCQuestion
|
||||||
form_class = MCQuestionForm
|
form_class = MCQuestionForm
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(MCQuestionCreate, self).get_context_data(**kwargs)
|
context = super(MCQuestionCreate, self).get_context_data(**kwargs)
|
||||||
context['course'] = Course.objects.get(slug=self.kwargs['slug'])
|
context["course"] = Course.objects.get(slug=self.kwargs["slug"])
|
||||||
context['quiz_obj'] = Quiz.objects.get(id=self.kwargs['quiz_id'])
|
context["quiz_obj"] = Quiz.objects.get(id=self.kwargs["quiz_id"])
|
||||||
context['quizQuestions'] = Question.objects.filter(quiz=self.kwargs['quiz_id']).count()
|
context["quizQuestions"] = Question.objects.filter(
|
||||||
|
quiz=self.kwargs["quiz_id"]
|
||||||
|
).count()
|
||||||
if self.request.POST:
|
if self.request.POST:
|
||||||
context['form'] = MCQuestionForm(self.request.POST)
|
context["form"] = MCQuestionForm(self.request.POST)
|
||||||
context['formset'] = MCQuestionFormSet(self.request.POST)
|
context["formset"] = MCQuestionFormSet(self.request.POST)
|
||||||
else:
|
else:
|
||||||
context['form'] = MCQuestionForm(initial={'quiz': self.kwargs['quiz_id']})
|
context["form"] = MCQuestionForm(initial={"quiz": self.kwargs["quiz_id"]})
|
||||||
context['formset'] = MCQuestionFormSet()
|
context["formset"] = MCQuestionFormSet()
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
context = self.get_context_data()
|
context = self.get_context_data()
|
||||||
formset = context['formset']
|
formset = context["formset"]
|
||||||
course = context['course']
|
course = context["course"]
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
form.instance.question = self.request.POST.get('content')
|
form.instance.question = self.request.POST.get("content")
|
||||||
self.object = form.save()
|
self.object = form.save()
|
||||||
if formset.is_valid():
|
if formset.is_valid():
|
||||||
formset.instance = self.object
|
formset.instance = self.object
|
||||||
formset.save()
|
formset.save()
|
||||||
if "another" in self.request.POST:
|
if "another" in self.request.POST:
|
||||||
return redirect('mc_create', slug=self.kwargs['slug'], quiz_id=self.kwargs['quiz_id'])
|
return redirect(
|
||||||
return redirect('quiz_index', course.slug)
|
"mc_create",
|
||||||
|
slug=self.kwargs["slug"],
|
||||||
|
quiz_id=self.kwargs["quiz_id"],
|
||||||
|
)
|
||||||
|
return redirect("quiz_index", course.slug)
|
||||||
return super(MCQuestionCreate, self).form_invalid(form)
|
return super(MCQuestionCreate, self).form_invalid(form)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def quiz_list(request, slug):
|
def quiz_list(request, slug):
|
||||||
quizzes = Quiz.objects.filter(course__slug = slug).order_by('-timestamp')
|
quizzes = Quiz.objects.filter(course__slug=slug).order_by("-timestamp")
|
||||||
course = Course.objects.get(slug=slug)
|
course = Course.objects.get(slug=slug)
|
||||||
return render(request, 'quiz/quiz_list.html', {'quizzes': quizzes, 'course': course})
|
return render(
|
||||||
|
request, "quiz/quiz_list.html", {"quizzes": quizzes, "course": course}
|
||||||
|
)
|
||||||
# return render(request, 'quiz/quiz_list.html', {'quizzes': quizzes})
|
# return render(request, 'quiz/quiz_list.html', {'quizzes': quizzes})
|
||||||
|
|
||||||
|
|
||||||
@method_decorator([login_required, lecturer_required], name='dispatch')
|
@method_decorator([login_required, lecturer_required], name="dispatch")
|
||||||
class QuizMarkerMixin(object):
|
class QuizMarkerMixin(object):
|
||||||
@method_decorator(login_required)
|
@method_decorator(login_required)
|
||||||
# @method_decorator(permission_required('quiz.view_sittings'))
|
# @method_decorator(permission_required('quiz.view_sittings'))
|
||||||
@ -136,16 +157,16 @@ class QuizMarkerMixin(object):
|
|||||||
class SittingFilterTitleMixin(object):
|
class SittingFilterTitleMixin(object):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
queryset = super(SittingFilterTitleMixin, self).get_queryset()
|
queryset = super(SittingFilterTitleMixin, self).get_queryset()
|
||||||
quiz_filter = self.request.GET.get('quiz_filter')
|
quiz_filter = self.request.GET.get("quiz_filter")
|
||||||
if quiz_filter:
|
if quiz_filter:
|
||||||
queryset = queryset.filter(quiz__title__icontains=quiz_filter)
|
queryset = queryset.filter(quiz__title__icontains=quiz_filter)
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
@method_decorator([login_required], name='dispatch')
|
@method_decorator([login_required], name="dispatch")
|
||||||
class QuizUserProgressView(TemplateView):
|
class QuizUserProgressView(TemplateView):
|
||||||
template_name = 'progress.html'
|
template_name = "progress.html"
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
return super(QuizUserProgressView, self).dispatch(request, *args, **kwargs)
|
return super(QuizUserProgressView, self).dispatch(request, *args, **kwargs)
|
||||||
@ -153,16 +174,19 @@ class QuizUserProgressView(TemplateView):
|
|||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(QuizUserProgressView, self).get_context_data(**kwargs)
|
context = super(QuizUserProgressView, self).get_context_data(**kwargs)
|
||||||
progress, c = Progress.objects.get_or_create(user=self.request.user)
|
progress, c = Progress.objects.get_or_create(user=self.request.user)
|
||||||
context['cat_scores'] = progress.list_all_cat_scores
|
context["cat_scores"] = progress.list_all_cat_scores
|
||||||
context['exams'] = progress.show_exams()
|
context["exams"] = progress.show_exams()
|
||||||
context['exams_counter'] = progress.show_exams().count()
|
context["exams_counter"] = progress.show_exams().count()
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
from result.models import TakenCourse
|
from result.models import TakenCourse
|
||||||
|
|
||||||
@method_decorator([login_required, lecturer_required], name='dispatch')
|
|
||||||
|
@method_decorator([login_required, lecturer_required], name="dispatch")
|
||||||
class QuizMarkingList(QuizMarkerMixin, SittingFilterTitleMixin, ListView):
|
class QuizMarkingList(QuizMarkerMixin, SittingFilterTitleMixin, ListView):
|
||||||
model = Sitting
|
model = Sitting
|
||||||
|
|
||||||
# def get_context_data(self, **kwargs):
|
# def get_context_data(self, **kwargs):
|
||||||
# context = super(QuizMarkingList, self).get_context_data(**kwargs)
|
# context = super(QuizMarkingList, self).get_context_data(**kwargs)
|
||||||
# context['queryset_counter'] = super(QuizMarkingList, self).get_queryset().filter(complete=True).filter(course__allocated_course__lecturer__pk=self.request.user.id).count()
|
# context['queryset_counter'] = super(QuizMarkingList, self).get_queryset().filter(complete=True).filter(course__allocated_course__lecturer__pk=self.request.user.id).count()
|
||||||
@ -172,24 +196,31 @@ class QuizMarkingList(QuizMarkerMixin, SittingFilterTitleMixin, ListView):
|
|||||||
if self.request.user.is_superuser:
|
if self.request.user.is_superuser:
|
||||||
queryset = super(QuizMarkingList, self).get_queryset().filter(complete=True)
|
queryset = super(QuizMarkingList, self).get_queryset().filter(complete=True)
|
||||||
else:
|
else:
|
||||||
queryset = super(QuizMarkingList, self).get_queryset().filter(quiz__course__allocated_course__lecturer__pk=self.request.user.id).filter(complete=True)
|
queryset = (
|
||||||
|
super(QuizMarkingList, self)
|
||||||
|
.get_queryset()
|
||||||
|
.filter(
|
||||||
|
quiz__course__allocated_course__lecturer__pk=self.request.user.id
|
||||||
|
)
|
||||||
|
.filter(complete=True)
|
||||||
|
)
|
||||||
|
|
||||||
# search by user
|
# search by user
|
||||||
user_filter = self.request.GET.get('user_filter')
|
user_filter = self.request.GET.get("user_filter")
|
||||||
if user_filter:
|
if user_filter:
|
||||||
queryset = queryset.filter(user__username__icontains=user_filter)
|
queryset = queryset.filter(user__username__icontains=user_filter)
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
@method_decorator([login_required, lecturer_required], name='dispatch')
|
@method_decorator([login_required, lecturer_required], name="dispatch")
|
||||||
class QuizMarkingDetail(QuizMarkerMixin, DetailView):
|
class QuizMarkingDetail(QuizMarkerMixin, DetailView):
|
||||||
model = Sitting
|
model = Sitting
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
sitting = self.get_object()
|
sitting = self.get_object()
|
||||||
|
|
||||||
q_to_toggle = request.POST.get('qid', None)
|
q_to_toggle = request.POST.get("qid", None)
|
||||||
if q_to_toggle:
|
if q_to_toggle:
|
||||||
q = Question.objects.get_subclass(id=int(q_to_toggle))
|
q = Question.objects.get_subclass(id=int(q_to_toggle))
|
||||||
if int(q_to_toggle) in sitting.get_incorrect_questions:
|
if int(q_to_toggle) in sitting.get_incorrect_questions:
|
||||||
@ -201,37 +232,42 @@ class QuizMarkingDetail(QuizMarkerMixin, DetailView):
|
|||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(QuizMarkingDetail, self).get_context_data(**kwargs)
|
context = super(QuizMarkingDetail, self).get_context_data(**kwargs)
|
||||||
context['questions'] = context['sitting'].get_questions(with_answers=True)
|
context["questions"] = context["sitting"].get_questions(with_answers=True)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
# @method_decorator([login_required, student_required], name='dispatch')
|
# @method_decorator([login_required, student_required], name='dispatch')
|
||||||
@method_decorator([login_required], name='dispatch')
|
@method_decorator([login_required], name="dispatch")
|
||||||
class QuizTake(FormView):
|
class QuizTake(FormView):
|
||||||
form_class = QuestionForm
|
form_class = QuestionForm
|
||||||
template_name = 'question.html'
|
template_name = "question.html"
|
||||||
result_template_name = 'result.html'
|
result_template_name = "result.html"
|
||||||
# single_complete_template_name = 'single_complete.html'
|
# single_complete_template_name = 'single_complete.html'
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
self.quiz = get_object_or_404(Quiz, slug=self.kwargs['slug'])
|
self.quiz = get_object_or_404(Quiz, slug=self.kwargs["slug"])
|
||||||
self.course = get_object_or_404(Course, pk=self.kwargs['pk'])
|
self.course = get_object_or_404(Course, pk=self.kwargs["pk"])
|
||||||
quizQuestions = Question.objects.filter(quiz=self.quiz).count()
|
quizQuestions = Question.objects.filter(quiz=self.quiz).count()
|
||||||
course = get_object_or_404(Course, pk=self.kwargs['pk'])
|
course = get_object_or_404(Course, pk=self.kwargs["pk"])
|
||||||
|
|
||||||
if quizQuestions <= 0:
|
if quizQuestions <= 0:
|
||||||
messages.warning(request, f'Question set of the quiz is empty. try later!')
|
messages.warning(request, f"Question set of the quiz is empty. try later!")
|
||||||
return redirect('quiz_index', self.course.slug)
|
return redirect("quiz_index", self.course.slug)
|
||||||
|
|
||||||
if self.quiz.draft and not request.user.has_perm('quiz.change_quiz'):
|
if self.quiz.draft and not request.user.has_perm("quiz.change_quiz"):
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
|
|
||||||
self.sitting = Sitting.objects.user_sitting(request.user, self.quiz, self.course)
|
self.sitting = Sitting.objects.user_sitting(
|
||||||
|
request.user, self.quiz, self.course
|
||||||
|
)
|
||||||
|
|
||||||
if self.sitting is False:
|
if self.sitting is False:
|
||||||
# return render(request, self.single_complete_template_name)
|
# return render(request, self.single_complete_template_name)
|
||||||
messages.info(request, f'You have already sat this exam and only one sitting is permitted')
|
messages.info(
|
||||||
return redirect('quiz_index', self.course.slug)
|
request,
|
||||||
|
f"You have already sat this exam and only one sitting is permitted",
|
||||||
|
)
|
||||||
|
return redirect("quiz_index", self.course.slug)
|
||||||
|
|
||||||
return super(QuizTake, self).dispatch(request, *args, **kwargs)
|
return super(QuizTake, self).dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
@ -262,18 +298,18 @@ class QuizTake(FormView):
|
|||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(QuizTake, self).get_context_data(**kwargs)
|
context = super(QuizTake, self).get_context_data(**kwargs)
|
||||||
context['question'] = self.question
|
context["question"] = self.question
|
||||||
context['quiz'] = self.quiz
|
context["quiz"] = self.quiz
|
||||||
context['course'] = get_object_or_404(Course, pk=self.kwargs['pk'])
|
context["course"] = get_object_or_404(Course, pk=self.kwargs["pk"])
|
||||||
if hasattr(self, 'previous'):
|
if hasattr(self, "previous"):
|
||||||
context['previous'] = self.previous
|
context["previous"] = self.previous
|
||||||
if hasattr(self, 'progress'):
|
if hasattr(self, "progress"):
|
||||||
context['progress'] = self.progress
|
context["progress"] = self.progress
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def form_valid_user(self, form):
|
def form_valid_user(self, form):
|
||||||
progress, c = Progress.objects.get_or_create(user=self.request.user)
|
progress, c = Progress.objects.get_or_create(user=self.request.user)
|
||||||
guess = form.cleaned_data['answers']
|
guess = form.cleaned_data["answers"]
|
||||||
is_correct = self.question.check_if_correct(guess)
|
is_correct = self.question.check_if_correct(guess)
|
||||||
|
|
||||||
if is_correct is True:
|
if is_correct is True:
|
||||||
@ -285,11 +321,11 @@ class QuizTake(FormView):
|
|||||||
|
|
||||||
if self.quiz.answers_at_end is not True:
|
if self.quiz.answers_at_end is not True:
|
||||||
self.previous = {
|
self.previous = {
|
||||||
'previous_answer': guess,
|
"previous_answer": guess,
|
||||||
'previous_outcome': is_correct,
|
"previous_outcome": is_correct,
|
||||||
'previous_question': self.question,
|
"previous_question": self.question,
|
||||||
'answers': self.question.get_choices(),
|
"answers": self.question.get_choices(),
|
||||||
'question_type': {self.question.__class__.__name__: True}
|
"question_type": {self.question.__class__.__name__: True},
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
self.previous = {}
|
self.previous = {}
|
||||||
@ -299,23 +335,27 @@ class QuizTake(FormView):
|
|||||||
|
|
||||||
def final_result_user(self):
|
def final_result_user(self):
|
||||||
results = {
|
results = {
|
||||||
'course': get_object_or_404(Course, pk=self.kwargs['pk']),
|
"course": get_object_or_404(Course, pk=self.kwargs["pk"]),
|
||||||
'quiz': self.quiz,
|
"quiz": self.quiz,
|
||||||
'score': self.sitting.get_current_score,
|
"score": self.sitting.get_current_score,
|
||||||
'max_score': self.sitting.get_max_score,
|
"max_score": self.sitting.get_max_score,
|
||||||
'percent': self.sitting.get_percent_correct,
|
"percent": self.sitting.get_percent_correct,
|
||||||
'sitting': self.sitting,
|
"sitting": self.sitting,
|
||||||
'previous': self.previous,
|
"previous": self.previous,
|
||||||
'course': get_object_or_404(Course, pk=self.kwargs['pk'])
|
"course": get_object_or_404(Course, pk=self.kwargs["pk"]),
|
||||||
}
|
}
|
||||||
|
|
||||||
self.sitting.mark_quiz_complete()
|
self.sitting.mark_quiz_complete()
|
||||||
|
|
||||||
if self.quiz.answers_at_end:
|
if self.quiz.answers_at_end:
|
||||||
results['questions'] = self.sitting.get_questions(with_answers=True)
|
results["questions"] = self.sitting.get_questions(with_answers=True)
|
||||||
results['incorrect_questions'] = self.sitting.get_incorrect_questions
|
results["incorrect_questions"] = self.sitting.get_incorrect_questions
|
||||||
|
|
||||||
if self.quiz.exam_paper is False or self.request.user.is_superuser or self.request.user.is_lecturer :
|
if (
|
||||||
|
self.quiz.exam_paper is False
|
||||||
|
or self.request.user.is_superuser
|
||||||
|
or self.request.user.is_lecturer
|
||||||
|
):
|
||||||
self.sitting.delete()
|
self.sitting.delete()
|
||||||
|
|
||||||
return render(self.request, self.result_template_name, results)
|
return render(self.request, self.result_template_name, results)
|
||||||
|
|||||||
@ -6,8 +6,16 @@ from .models import TakenCourse, Result
|
|||||||
|
|
||||||
class ScoreAdmin(admin.ModelAdmin):
|
class ScoreAdmin(admin.ModelAdmin):
|
||||||
list_display = [
|
list_display = [
|
||||||
'student', 'course', 'assignment', 'mid_exam', 'quiz',
|
"student",
|
||||||
'attendance', 'final_exam', 'total', 'grade', 'comment'
|
"course",
|
||||||
|
"assignment",
|
||||||
|
"mid_exam",
|
||||||
|
"quiz",
|
||||||
|
"attendance",
|
||||||
|
"final_exam",
|
||||||
|
"total",
|
||||||
|
"grade",
|
||||||
|
"comment",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
|
|
||||||
class ResultConfig(AppConfig):
|
class ResultConfig(AppConfig):
|
||||||
name = 'result'
|
name = "result"
|
||||||
|
|||||||
@ -6,12 +6,12 @@ from app.models import Session, Semester
|
|||||||
from course.models import Course
|
from course.models import Course
|
||||||
|
|
||||||
YEARS = (
|
YEARS = (
|
||||||
(1, '1'),
|
(1, "1"),
|
||||||
(2, '2'),
|
(2, "2"),
|
||||||
(3, '3'),
|
(3, "3"),
|
||||||
(4, '4'),
|
(4, "4"),
|
||||||
(4, '5'),
|
(4, "5"),
|
||||||
(4, '6'),
|
(4, "6"),
|
||||||
)
|
)
|
||||||
|
|
||||||
# LEVEL_COURSE = "Level course"
|
# LEVEL_COURSE = "Level course"
|
||||||
@ -84,7 +84,7 @@ class TakenCourseManager(models.Manager):
|
|||||||
else:
|
else:
|
||||||
cart_obj = Cart.objects.new(user=request.user)
|
cart_obj = Cart.objects.new(user=request.user)
|
||||||
new_obj = True
|
new_obj = True
|
||||||
request.session['cart_id'] = cart_obj.id
|
request.session["cart_id"] = cart_obj.id
|
||||||
return cart_obj, new_obj
|
return cart_obj, new_obj
|
||||||
|
|
||||||
def new(self, user=None):
|
def new(self, user=None):
|
||||||
@ -97,7 +97,9 @@ class TakenCourseManager(models.Manager):
|
|||||||
|
|
||||||
class TakenCourse(models.Model):
|
class TakenCourse(models.Model):
|
||||||
student = models.ForeignKey(Student, on_delete=models.CASCADE)
|
student = models.ForeignKey(Student, on_delete=models.CASCADE)
|
||||||
course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='taken_courses')
|
course = models.ForeignKey(
|
||||||
|
Course, on_delete=models.CASCADE, related_name="taken_courses"
|
||||||
|
)
|
||||||
assignment = models.DecimalField(max_digits=5, decimal_places=2, default=0.0)
|
assignment = models.DecimalField(max_digits=5, decimal_places=2, default=0.0)
|
||||||
mid_exam = models.DecimalField(max_digits=5, decimal_places=2, default=0.0)
|
mid_exam = models.DecimalField(max_digits=5, decimal_places=2, default=0.0)
|
||||||
quiz = models.DecimalField(max_digits=5, decimal_places=2, default=0.0)
|
quiz = models.DecimalField(max_digits=5, decimal_places=2, default=0.0)
|
||||||
@ -109,14 +111,20 @@ class TakenCourse(models.Model):
|
|||||||
comment = models.CharField(choices=COMMENT, max_length=200, blank=True)
|
comment = models.CharField(choices=COMMENT, max_length=200, blank=True)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('course_detail', kwargs={'slug': self.course.slug})
|
return reverse("course_detail", kwargs={"slug": self.course.slug})
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "{0} ({1})".format(self.course.title, self.course.code)
|
return "{0} ({1})".format(self.course.title, self.course.code)
|
||||||
|
|
||||||
# @staticmethod
|
# @staticmethod
|
||||||
def get_total(self, assignment, mid_exam, quiz, attendance, final_exam):
|
def get_total(self, assignment, mid_exam, quiz, attendance, final_exam):
|
||||||
return float(assignment) + float(mid_exam) + float(quiz) + float(attendance) + float(final_exam)
|
return (
|
||||||
|
float(assignment)
|
||||||
|
+ float(mid_exam)
|
||||||
|
+ float(quiz)
|
||||||
|
+ float(attendance)
|
||||||
|
+ float(final_exam)
|
||||||
|
)
|
||||||
|
|
||||||
# @staticmethod
|
# @staticmethod
|
||||||
def get_grade(self, total):
|
def get_grade(self, total):
|
||||||
@ -191,7 +199,11 @@ class TakenCourse(models.Model):
|
|||||||
|
|
||||||
def calculate_gpa(self, total_credit_in_semester):
|
def calculate_gpa(self, total_credit_in_semester):
|
||||||
current_semester = Semester.objects.get(is_current_semester=True)
|
current_semester = Semester.objects.get(is_current_semester=True)
|
||||||
student = TakenCourse.objects.filter(student=self.student, course__level=self.student.level, course__semester=current_semester)
|
student = TakenCourse.objects.filter(
|
||||||
|
student=self.student,
|
||||||
|
course__level=self.student.level,
|
||||||
|
course__semester=current_semester,
|
||||||
|
)
|
||||||
p = 0
|
p = 0
|
||||||
point = 0
|
point = 0
|
||||||
for i in student:
|
for i in student:
|
||||||
@ -220,14 +232,16 @@ class TakenCourse(models.Model):
|
|||||||
point = 0
|
point = 0
|
||||||
p += int(credit) * point
|
p += int(credit) * point
|
||||||
try:
|
try:
|
||||||
gpa = (p / total_credit_in_semester)
|
gpa = p / total_credit_in_semester
|
||||||
return round(gpa, 2)
|
return round(gpa, 2)
|
||||||
except ZeroDivisionError:
|
except ZeroDivisionError:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def calculate_cgpa(self):
|
def calculate_cgpa(self):
|
||||||
current_semester = Semester.objects.get(is_current_semester=True)
|
current_semester = Semester.objects.get(is_current_semester=True)
|
||||||
previousResult = Result.objects.filter(student__id=self.student.id, level__lt=self.student.level)
|
previousResult = Result.objects.filter(
|
||||||
|
student__id=self.student.id, level__lt=self.student.level
|
||||||
|
)
|
||||||
previousCGPA = 0
|
previousCGPA = 0
|
||||||
for i in previousResult:
|
for i in previousResult:
|
||||||
if i.cgpa is not None:
|
if i.cgpa is not None:
|
||||||
@ -237,18 +251,24 @@ class TakenCourse(models.Model):
|
|||||||
first_sem_gpa = 0.0
|
first_sem_gpa = 0.0
|
||||||
sec_sem_gpa = 0.0
|
sec_sem_gpa = 0.0
|
||||||
try:
|
try:
|
||||||
first_sem_result = Result.objects.get(student=self.student.id, semester=FIRST, level=self.student.level)
|
first_sem_result = Result.objects.get(
|
||||||
|
student=self.student.id, semester=FIRST, level=self.student.level
|
||||||
|
)
|
||||||
first_sem_gpa += first_sem_result.gpa
|
first_sem_gpa += first_sem_result.gpa
|
||||||
except:
|
except:
|
||||||
first_sem_gpa = 0
|
first_sem_gpa = 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sec_sem_result = Result.objects.get(student=self.student.id, semester=SECOND, level=self.student.level)
|
sec_sem_result = Result.objects.get(
|
||||||
|
student=self.student.id, semester=SECOND, level=self.student.level
|
||||||
|
)
|
||||||
sec_sem_gpa += sec_sem_result.gpa
|
sec_sem_gpa += sec_sem_result.gpa
|
||||||
except:
|
except:
|
||||||
sec_sem_gpa = 0
|
sec_sem_gpa = 0
|
||||||
|
|
||||||
taken_courses = TakenCourse.objects.filter(student=self.student, student__level=self.student.level)
|
taken_courses = TakenCourse.objects.filter(
|
||||||
|
student=self.student, student__level=self.student.level
|
||||||
|
)
|
||||||
TCC = 0
|
TCC = 0
|
||||||
TCP = 0
|
TCP = 0
|
||||||
for i in taken_courses:
|
for i in taken_courses:
|
||||||
|
|||||||
@ -1,17 +1,21 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
from .views import (
|
from .views import (
|
||||||
add_score, add_score_for, grade_result, assessment_result,
|
add_score,
|
||||||
course_registration_form, result_sheet_pdf_view
|
add_score_for,
|
||||||
|
grade_result,
|
||||||
|
assessment_result,
|
||||||
|
course_registration_form,
|
||||||
|
result_sheet_pdf_view,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('manage-score/', add_score, name='add_score'),
|
path("manage-score/", add_score, name="add_score"),
|
||||||
path('manage-score/<int:id>/', add_score_for, name='add_score_for'),
|
path("manage-score/<int:id>/", add_score_for, name="add_score_for"),
|
||||||
|
path("grade/", grade_result, name="grade_results"),
|
||||||
path('grade/', grade_result, name="grade_results"),
|
path("assessment/", assessment_result, name="ass_results"),
|
||||||
path('assessment/', assessment_result, name="ass_results"),
|
path("result/print/<int:id>/", result_sheet_pdf_view, name="result_sheet_pdf_view"),
|
||||||
|
path(
|
||||||
path('result/print/<int:id>/', result_sheet_pdf_view, name='result_sheet_pdf_view'),
|
"registration/form/", course_registration_form, name="course_registration_form"
|
||||||
path('registration/form/', course_registration_form, name='course_registration_form'),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
438
result/views.py
438
result/views.py
@ -16,7 +16,15 @@ from .models import TakenCourse, Result
|
|||||||
from django.core.files.storage import FileSystemStorage
|
from django.core.files.storage import FileSystemStorage
|
||||||
from django.http import HttpResponse, JsonResponse
|
from django.http import HttpResponse, JsonResponse
|
||||||
|
|
||||||
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Image, LongTable
|
from reportlab.platypus import (
|
||||||
|
SimpleDocTemplate,
|
||||||
|
Paragraph,
|
||||||
|
Spacer,
|
||||||
|
Table,
|
||||||
|
TableStyle,
|
||||||
|
Image,
|
||||||
|
LongTable,
|
||||||
|
)
|
||||||
from reportlab.lib.styles import getSampleStyleSheet, black, ParagraphStyle
|
from reportlab.lib.styles import getSampleStyleSheet, black, ParagraphStyle
|
||||||
from reportlab.lib.enums import TA_JUSTIFY, TA_LEFT, TA_CENTER, TA_RIGHT
|
from reportlab.lib.enums import TA_JUSTIFY, TA_LEFT, TA_CENTER, TA_RIGHT
|
||||||
from reportlab.platypus.tables import Table
|
from reportlab.platypus.tables import Table
|
||||||
@ -26,6 +34,7 @@ from .models import *
|
|||||||
|
|
||||||
cm = 2.54
|
cm = 2.54
|
||||||
|
|
||||||
|
|
||||||
# ########################################################
|
# ########################################################
|
||||||
# Score Add & Add for
|
# Score Add & Add for
|
||||||
# ########################################################
|
# ########################################################
|
||||||
@ -38,15 +47,19 @@ def add_score(request):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
current_session = Session.objects.get(is_current_session=True)
|
current_session = Session.objects.get(is_current_session=True)
|
||||||
current_semester = get_object_or_404(Semester, is_current_semester=True, session=current_session)
|
current_semester = get_object_or_404(
|
||||||
|
Semester, is_current_semester=True, session=current_session
|
||||||
|
)
|
||||||
# semester = Course.objects.filter(allocated_course__lecturer__pk=request.user.id, semester=current_semester)
|
# semester = Course.objects.filter(allocated_course__lecturer__pk=request.user.id, semester=current_semester)
|
||||||
courses = Course.objects.filter(allocated_course__lecturer__pk=request.user.id).filter(semester=current_semester)
|
courses = Course.objects.filter(
|
||||||
|
allocated_course__lecturer__pk=request.user.id
|
||||||
|
).filter(semester=current_semester)
|
||||||
context = {
|
context = {
|
||||||
"current_session": current_session,
|
"current_session": current_session,
|
||||||
"current_semester": current_semester,
|
"current_semester": current_semester,
|
||||||
"courses": courses,
|
"courses": courses,
|
||||||
}
|
}
|
||||||
return render(request, 'result/add_score.html', context)
|
return render(request, "result/add_score.html", context)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -57,10 +70,13 @@ def add_score_for(request, id):
|
|||||||
in a specific semester and session
|
in a specific semester and session
|
||||||
"""
|
"""
|
||||||
current_session = Session.objects.get(is_current_session=True)
|
current_session = Session.objects.get(is_current_session=True)
|
||||||
current_semester = get_object_or_404(Semester, is_current_semester=True, session=current_session)
|
current_semester = get_object_or_404(
|
||||||
if request.method == 'GET':
|
Semester, is_current_semester=True, session=current_session
|
||||||
courses = Course.objects.filter(allocated_course__lecturer__pk=request.user.id).filter(
|
)
|
||||||
semester=current_semester)
|
if request.method == "GET":
|
||||||
|
courses = Course.objects.filter(
|
||||||
|
allocated_course__lecturer__pk=request.user.id
|
||||||
|
).filter(semester=current_semester)
|
||||||
course = Course.objects.get(pk=id)
|
course = Course.objects.get(pk=id)
|
||||||
# myclass = Class.objects.get(lecturer__pk=request.user.id)
|
# myclass = Class.objects.get(lecturer__pk=request.user.id)
|
||||||
# myclass = get_object_or_404(Class, lecturer__pk=request.user.id)
|
# myclass = get_object_or_404(Class, lecturer__pk=request.user.id)
|
||||||
@ -68,8 +84,13 @@ def add_score_for(request, id):
|
|||||||
# students = TakenCourse.objects.filter(course__allocated_course__lecturer__pk=request.user.id).filter(
|
# students = TakenCourse.objects.filter(course__allocated_course__lecturer__pk=request.user.id).filter(
|
||||||
# course__id=id).filter(student__allocated_student__lecturer__pk=request.user.id).filter(
|
# course__id=id).filter(student__allocated_student__lecturer__pk=request.user.id).filter(
|
||||||
# course__semester=current_semester)
|
# course__semester=current_semester)
|
||||||
students = TakenCourse.objects.filter(course__allocated_course__lecturer__pk=request.user.id).filter(
|
students = (
|
||||||
course__id=id).filter(course__semester=current_semester)
|
TakenCourse.objects.filter(
|
||||||
|
course__allocated_course__lecturer__pk=request.user.id
|
||||||
|
)
|
||||||
|
.filter(course__id=id)
|
||||||
|
.filter(course__semester=current_semester)
|
||||||
|
)
|
||||||
context = {
|
context = {
|
||||||
"title": "Submit Score | DjangoSMS",
|
"title": "Submit Score | DjangoSMS",
|
||||||
"courses": courses,
|
"courses": courses,
|
||||||
@ -79,29 +100,40 @@ def add_score_for(request, id):
|
|||||||
"current_session": current_session,
|
"current_session": current_session,
|
||||||
"current_semester": current_semester,
|
"current_semester": current_semester,
|
||||||
}
|
}
|
||||||
return render(request, 'result/add_score_for.html', context)
|
return render(request, "result/add_score_for.html", context)
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
ids = ()
|
ids = ()
|
||||||
data = request.POST.copy()
|
data = request.POST.copy()
|
||||||
data.pop('csrfmiddlewaretoken', None) # remove csrf_token
|
data.pop("csrfmiddlewaretoken", None) # remove csrf_token
|
||||||
for key in data.keys():
|
for key in data.keys():
|
||||||
ids = ids + (str(key),) # gather all the all students id (i.e the keys) in a tuple
|
ids = ids + (
|
||||||
for s in range(0, len(ids)): # iterate over the list of student ids gathered above
|
str(key),
|
||||||
|
) # gather all the all students id (i.e the keys) in a tuple
|
||||||
|
for s in range(
|
||||||
|
0, len(ids)
|
||||||
|
): # iterate over the list of student ids gathered above
|
||||||
student = TakenCourse.objects.get(id=ids[s])
|
student = TakenCourse.objects.get(id=ids[s])
|
||||||
# print(student)
|
# print(student)
|
||||||
# print(student.student)
|
# print(student.student)
|
||||||
# print(student.student.department.id)
|
# print(student.student.department.id)
|
||||||
courses = Course.objects.filter(level=student.student.level).filter(program__pk=student.student.department.id).filter(
|
courses = (
|
||||||
semester=current_semester) # all courses of a specific level in current semester
|
Course.objects.filter(level=student.student.level)
|
||||||
|
.filter(program__pk=student.student.department.id)
|
||||||
|
.filter(semester=current_semester)
|
||||||
|
) # all courses of a specific level in current semester
|
||||||
total_credit_in_semester = 0
|
total_credit_in_semester = 0
|
||||||
for i in courses:
|
for i in courses:
|
||||||
if i == courses.count():
|
if i == courses.count():
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
total_credit_in_semester += int(i.credit)
|
total_credit_in_semester += int(i.credit)
|
||||||
score = data.getlist(ids[s]) # get list of score for current student in the loop
|
score = data.getlist(
|
||||||
assignment = score[0] # subscript the list to get the fisrt value > ca score
|
ids[s]
|
||||||
|
) # get list of score for current student in the loop
|
||||||
|
assignment = score[
|
||||||
|
0
|
||||||
|
] # subscript the list to get the fisrt value > ca score
|
||||||
mid_exam = score[1] # do the same for exam score
|
mid_exam = score[1] # do the same for exam score
|
||||||
quiz = score[2]
|
quiz = score[2]
|
||||||
attendance = score[3]
|
attendance = score[3]
|
||||||
@ -113,7 +145,13 @@ def add_score_for(request, id):
|
|||||||
obj.attendance = attendance # set current student attendance score
|
obj.attendance = attendance # set current student attendance score
|
||||||
obj.final_exam = final_exam # set current student final_exam score
|
obj.final_exam = final_exam # set current student final_exam score
|
||||||
|
|
||||||
obj.total = obj.get_total(assignment=assignment, mid_exam=mid_exam, quiz=quiz, attendance=attendance, final_exam=final_exam)
|
obj.total = obj.get_total(
|
||||||
|
assignment=assignment,
|
||||||
|
mid_exam=mid_exam,
|
||||||
|
quiz=quiz,
|
||||||
|
attendance=attendance,
|
||||||
|
final_exam=final_exam,
|
||||||
|
)
|
||||||
obj.grade = obj.get_grade(total=obj.total)
|
obj.grade = obj.get_grade(total=obj.total)
|
||||||
|
|
||||||
# obj.total = obj.get_total(assignment, mid_exam, quiz, attendance, final_exam)
|
# obj.total = obj.get_total(assignment, mid_exam, quiz, attendance, final_exam)
|
||||||
@ -129,13 +167,23 @@ def add_score_for(request, id):
|
|||||||
cgpa = obj.calculate_cgpa()
|
cgpa = obj.calculate_cgpa()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
a = Result.objects.get(student=student.student, semester=current_semester, session=current_session, level=student.student.level)
|
a = Result.objects.get(
|
||||||
|
student=student.student,
|
||||||
|
semester=current_semester,
|
||||||
|
session=current_session,
|
||||||
|
level=student.student.level,
|
||||||
|
)
|
||||||
a.gpa = gpa
|
a.gpa = gpa
|
||||||
a.cgpa = cgpa
|
a.cgpa = cgpa
|
||||||
a.save()
|
a.save()
|
||||||
except:
|
except:
|
||||||
Result.objects.get_or_create(student=student.student, gpa=gpa, semester=current_semester,
|
Result.objects.get_or_create(
|
||||||
session=current_session, level=student.student.level)
|
student=student.student,
|
||||||
|
gpa=gpa,
|
||||||
|
semester=current_semester,
|
||||||
|
session=current_session,
|
||||||
|
level=student.student.level,
|
||||||
|
)
|
||||||
|
|
||||||
# try:
|
# try:
|
||||||
# a = Result.objects.get(student=student.student, semester=current_semester, level=student.student.level)
|
# a = Result.objects.get(student=student.student, semester=current_semester, level=student.student.level)
|
||||||
@ -145,9 +193,11 @@ def add_score_for(request, id):
|
|||||||
# except:
|
# except:
|
||||||
# Result.objects.get_or_create(student=student.student, gpa=gpa, semester=current_semester, level=student.student.level)
|
# Result.objects.get_or_create(student=student.student, gpa=gpa, semester=current_semester, level=student.student.level)
|
||||||
|
|
||||||
messages.success(request, 'Successfully Recorded! ')
|
messages.success(request, "Successfully Recorded! ")
|
||||||
return HttpResponseRedirect(reverse_lazy('add_score_for', kwargs={'id': id}))
|
return HttpResponseRedirect(reverse_lazy("add_score_for", kwargs={"id": id}))
|
||||||
return HttpResponseRedirect(reverse_lazy('add_score_for', kwargs={'id': id}))
|
return HttpResponseRedirect(reverse_lazy("add_score_for", kwargs={"id": id}))
|
||||||
|
|
||||||
|
|
||||||
# ########################################################
|
# ########################################################
|
||||||
|
|
||||||
|
|
||||||
@ -155,7 +205,9 @@ def add_score_for(request, id):
|
|||||||
@student_required
|
@student_required
|
||||||
def grade_result(request):
|
def grade_result(request):
|
||||||
student = Student.objects.get(student__pk=request.user.id)
|
student = Student.objects.get(student__pk=request.user.id)
|
||||||
courses = TakenCourse.objects.filter(student__student__pk=request.user.id).filter(course__level=student.level)
|
courses = TakenCourse.objects.filter(student__student__pk=request.user.id).filter(
|
||||||
|
course__level=student.level
|
||||||
|
)
|
||||||
# total_credit_in_semester = 0
|
# total_credit_in_semester = 0
|
||||||
results = Result.objects.filter(student__student__pk=request.user.id)
|
results = Result.objects.filter(student__student__pk=request.user.id)
|
||||||
|
|
||||||
@ -180,7 +232,11 @@ def grade_result(request):
|
|||||||
for i in results:
|
for i in results:
|
||||||
previousLEVEL = i.level
|
previousLEVEL = i.level
|
||||||
try:
|
try:
|
||||||
a = Result.objects.get(student__student__pk=request.user.id, level=previousLEVEL, semester="Second")
|
a = Result.objects.get(
|
||||||
|
student__student__pk=request.user.id,
|
||||||
|
level=previousLEVEL,
|
||||||
|
semester="Second",
|
||||||
|
)
|
||||||
previousCGPA = a.cgpa
|
previousCGPA = a.cgpa
|
||||||
break
|
break
|
||||||
except:
|
except:
|
||||||
@ -191,20 +247,23 @@ def grade_result(request):
|
|||||||
"results": results,
|
"results": results,
|
||||||
"sorted_result": sorted_result,
|
"sorted_result": sorted_result,
|
||||||
"student": student,
|
"student": student,
|
||||||
'total_first_semester_credit': total_first_semester_credit,
|
"total_first_semester_credit": total_first_semester_credit,
|
||||||
'total_sec_semester_credit': total_sec_semester_credit,
|
"total_sec_semester_credit": total_sec_semester_credit,
|
||||||
'total_first_and_second_semester_credit': total_first_semester_credit + total_sec_semester_credit,
|
"total_first_and_second_semester_credit": total_first_semester_credit
|
||||||
|
+ total_sec_semester_credit,
|
||||||
"previousCGPA": previousCGPA,
|
"previousCGPA": previousCGPA,
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'result/grade_results.html', context)
|
return render(request, "result/grade_results.html", context)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@student_required
|
@student_required
|
||||||
def assessment_result(request):
|
def assessment_result(request):
|
||||||
student = Student.objects.get(student__pk=request.user.id)
|
student = Student.objects.get(student__pk=request.user.id)
|
||||||
courses = TakenCourse.objects.filter(student__student__pk=request.user.id, course__level=student.level)
|
courses = TakenCourse.objects.filter(
|
||||||
|
student__student__pk=request.user.id, course__level=student.level
|
||||||
|
)
|
||||||
result = Result.objects.filter(student__student__pk=request.user.id)
|
result = Result.objects.filter(student__student__pk=request.user.id)
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
@ -213,7 +272,7 @@ def assessment_result(request):
|
|||||||
"student": student,
|
"student": student,
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'result/assessment_results.html', context)
|
return render(request, "result/assessment_results.html", context)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -225,14 +284,29 @@ def result_sheet_pdf_view(request, id):
|
|||||||
course = get_object_or_404(Course, id=id)
|
course = get_object_or_404(Course, id=id)
|
||||||
no_of_pass = TakenCourse.objects.filter(course__pk=id, comment="PASS").count()
|
no_of_pass = TakenCourse.objects.filter(course__pk=id, comment="PASS").count()
|
||||||
no_of_fail = TakenCourse.objects.filter(course__pk=id, comment="FAIL").count()
|
no_of_fail = TakenCourse.objects.filter(course__pk=id, comment="FAIL").count()
|
||||||
fname = str(current_semester) + '_semester_' + str(current_session) + '_' + str(course) + '_resultSheet.pdf'
|
fname = (
|
||||||
|
str(current_semester)
|
||||||
|
+ "_semester_"
|
||||||
|
+ str(current_session)
|
||||||
|
+ "_"
|
||||||
|
+ str(course)
|
||||||
|
+ "_resultSheet.pdf"
|
||||||
|
)
|
||||||
fname = fname.replace("/", "-")
|
fname = fname.replace("/", "-")
|
||||||
flocation = settings.MEDIA_ROOT + "/result_sheet/" + fname
|
flocation = settings.MEDIA_ROOT + "/result_sheet/" + fname
|
||||||
|
|
||||||
doc = SimpleDocTemplate(flocation, rightMargin=0, leftMargin=6.5 * cm, topMargin=0.3 * cm, bottomMargin=0)
|
doc = SimpleDocTemplate(
|
||||||
|
flocation,
|
||||||
|
rightMargin=0,
|
||||||
|
leftMargin=6.5 * cm,
|
||||||
|
topMargin=0.3 * cm,
|
||||||
|
bottomMargin=0,
|
||||||
|
)
|
||||||
styles = getSampleStyleSheet()
|
styles = getSampleStyleSheet()
|
||||||
styles.add(ParagraphStyle( name="ParagraphTitle", fontSize=11, fontName="FreeSansBold"))
|
styles.add(
|
||||||
Story = [Spacer(1,.2)]
|
ParagraphStyle(name="ParagraphTitle", fontSize=11, fontName="FreeSansBold")
|
||||||
|
)
|
||||||
|
Story = [Spacer(1, 0.2)]
|
||||||
style = styles["Normal"]
|
style = styles["Normal"]
|
||||||
|
|
||||||
# picture = request.user.picture
|
# picture = request.user.picture
|
||||||
@ -261,7 +335,13 @@ def result_sheet_pdf_view(request, id):
|
|||||||
normal.fontName = "Helvetica"
|
normal.fontName = "Helvetica"
|
||||||
normal.fontSize = 12
|
normal.fontSize = 12
|
||||||
normal.leading = 15
|
normal.leading = 15
|
||||||
title = "<b> "+str(current_semester) + " Semester " + str(current_session) + " Result Sheet</b>"
|
title = (
|
||||||
|
"<b> "
|
||||||
|
+ str(current_semester)
|
||||||
|
+ " Semester "
|
||||||
|
+ str(current_session)
|
||||||
|
+ " Result Sheet</b>"
|
||||||
|
)
|
||||||
title = Paragraph(title.upper(), normal)
|
title = Paragraph(title.upper(), normal)
|
||||||
Story.append(title)
|
Story.append(title)
|
||||||
Story.append(Spacer(1, 0.1 * inch))
|
Story.append(Spacer(1, 0.1 * inch))
|
||||||
@ -286,46 +366,74 @@ def result_sheet_pdf_view(request, id):
|
|||||||
title = "<b>Level: </b>" + str(level.course.level)
|
title = "<b>Level: </b>" + str(level.course.level)
|
||||||
title = Paragraph(title.upper(), normal)
|
title = Paragraph(title.upper(), normal)
|
||||||
Story.append(title)
|
Story.append(title)
|
||||||
Story.append(Spacer(1,.6*inch))
|
Story.append(Spacer(1, 0.6 * inch))
|
||||||
|
|
||||||
elements = []
|
elements = []
|
||||||
count = 0
|
count = 0
|
||||||
header = [('S/N', 'ID NO.', 'FULL NAME', 'TOTAL', 'GRADE', 'POINT', 'COMMENT')]
|
header = [("S/N", "ID NO.", "FULL NAME", "TOTAL", "GRADE", "POINT", "COMMENT")]
|
||||||
|
|
||||||
table_header = Table(header, [inch], [0.5 * inch])
|
table_header = Table(header, [inch], [0.5 * inch])
|
||||||
table_header.setStyle(
|
table_header.setStyle(
|
||||||
TableStyle([
|
TableStyle(
|
||||||
('BACKGROUND',(0,0),(-1,-1),colors.black),
|
[
|
||||||
('TEXTCOLOR',(1,0),(-1,-1),colors.white),
|
("BACKGROUND", (0, 0), (-1, -1), colors.black),
|
||||||
('TEXTCOLOR',(0,0),(0,0),colors.cyan),
|
("TEXTCOLOR", (1, 0), (-1, -1), colors.white),
|
||||||
('ALIGN',(0,0),(-1,-1),'CENTER'),
|
("TEXTCOLOR", (0, 0), (0, 0), colors.cyan),
|
||||||
('VALIGN',(0,0),(-1,-1),'MIDDLE'),
|
("ALIGN", (0, 0), (-1, -1), "CENTER"),
|
||||||
('BOX',(0,0),(-1,-1),1,colors.black),
|
("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
|
||||||
]))
|
("BOX", (0, 0), (-1, -1), 1, colors.black),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
Story.append(table_header)
|
Story.append(table_header)
|
||||||
|
|
||||||
for student in result:
|
for student in result:
|
||||||
|
data = [
|
||||||
data = [(count+1, student.student.student.username.upper(), Paragraph(student.student.student.get_full_name.capitalize(), styles['Normal']),
|
(
|
||||||
student.total, student.grade, student.point, student.comment)]
|
count + 1,
|
||||||
|
student.student.student.username.upper(),
|
||||||
|
Paragraph(
|
||||||
|
student.student.student.get_full_name.capitalize(), styles["Normal"]
|
||||||
|
),
|
||||||
|
student.total,
|
||||||
|
student.grade,
|
||||||
|
student.point,
|
||||||
|
student.comment,
|
||||||
|
)
|
||||||
|
]
|
||||||
color = colors.black
|
color = colors.black
|
||||||
if student.grade == 'F':
|
if student.grade == "F":
|
||||||
color = colors.red
|
color = colors.red
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
t_body = Table(data, colWidths=[inch])
|
t_body = Table(data, colWidths=[inch])
|
||||||
t_body.setStyle(
|
t_body.setStyle(
|
||||||
TableStyle([
|
TableStyle(
|
||||||
('INNERGRID', (0,0), (-1,-1), 0.05, colors.black),
|
[
|
||||||
('BOX', (0,0), (-1,-1), 0.1, colors.black),
|
("INNERGRID", (0, 0), (-1, -1), 0.05, colors.black),
|
||||||
]))
|
("BOX", (0, 0), (-1, -1), 0.1, colors.black),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
Story.append(t_body)
|
Story.append(t_body)
|
||||||
|
|
||||||
Story.append(Spacer(1, 1 * inch))
|
Story.append(Spacer(1, 1 * inch))
|
||||||
style_right = ParagraphStyle(name='right', parent=styles['Normal'], alignment=TA_RIGHT)
|
style_right = ParagraphStyle(
|
||||||
|
name="right", parent=styles["Normal"], alignment=TA_RIGHT
|
||||||
|
)
|
||||||
tbl_data = [
|
tbl_data = [
|
||||||
[Paragraph("<b>Date:</b>_____________________________", styles["Normal"]), Paragraph("<b>No. of PASS:</b> " + str(no_of_pass), style_right)],
|
[
|
||||||
[Paragraph("<b>Siganture / Stamp:</b> _____________________________", styles["Normal"]), Paragraph("<b>No. of FAIL: </b>" + str(no_of_fail), style_right)]]
|
Paragraph("<b>Date:</b>_____________________________", styles["Normal"]),
|
||||||
|
Paragraph("<b>No. of PASS:</b> " + str(no_of_pass), style_right),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
Paragraph(
|
||||||
|
"<b>Siganture / Stamp:</b> _____________________________",
|
||||||
|
styles["Normal"],
|
||||||
|
),
|
||||||
|
Paragraph("<b>No. of FAIL: </b>" + str(no_of_fail), style_right),
|
||||||
|
],
|
||||||
|
]
|
||||||
tbl = Table(tbl_data)
|
tbl = Table(tbl_data)
|
||||||
Story.append(tbl)
|
Story.append(tbl)
|
||||||
|
|
||||||
@ -333,8 +441,8 @@ def result_sheet_pdf_view(request, id):
|
|||||||
|
|
||||||
fs = FileSystemStorage(settings.MEDIA_ROOT + "/result_sheet")
|
fs = FileSystemStorage(settings.MEDIA_ROOT + "/result_sheet")
|
||||||
with fs.open(fname) as pdf:
|
with fs.open(fname) as pdf:
|
||||||
response = HttpResponse(pdf, content_type='application/pdf')
|
response = HttpResponse(pdf, content_type="application/pdf")
|
||||||
response['Content-Disposition'] = 'inline; filename=' + fname + ''
|
response["Content-Disposition"] = "inline; filename=" + fname + ""
|
||||||
return response
|
return response
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@ -345,12 +453,14 @@ def course_registration_form(request):
|
|||||||
current_semester = Semester.objects.get(is_current_semester=True)
|
current_semester = Semester.objects.get(is_current_semester=True)
|
||||||
current_session = Session.objects.get(is_current_session=True)
|
current_session = Session.objects.get(is_current_session=True)
|
||||||
courses = TakenCourse.objects.filter(student__student__id=request.user.id)
|
courses = TakenCourse.objects.filter(student__student__id=request.user.id)
|
||||||
fname = request.user.username + '.pdf'
|
fname = request.user.username + ".pdf"
|
||||||
fname = fname.replace("/", "-")
|
fname = fname.replace("/", "-")
|
||||||
# flocation = '/tmp/' + fname
|
# flocation = '/tmp/' + fname
|
||||||
# print(MEDIA_ROOT + "\\" + fname)
|
# print(MEDIA_ROOT + "\\" + fname)
|
||||||
flocation = settings.MEDIA_ROOT + "/registration_form/" + fname
|
flocation = settings.MEDIA_ROOT + "/registration_form/" + fname
|
||||||
doc = SimpleDocTemplate(flocation, rightMargin=15, leftMargin=15, topMargin=0, bottomMargin=0)
|
doc = SimpleDocTemplate(
|
||||||
|
flocation, rightMargin=15, leftMargin=15, topMargin=0, bottomMargin=0
|
||||||
|
)
|
||||||
styles = getSampleStyleSheet()
|
styles = getSampleStyleSheet()
|
||||||
|
|
||||||
Story = [Spacer(1, 0.5)]
|
Story = [Spacer(1, 0.5)]
|
||||||
@ -387,19 +497,35 @@ def course_registration_form(request):
|
|||||||
department_title = "<b>DEPARTMENT OF COMPUTER SCIENCE & ENGINEERING</b>"
|
department_title = "<b>DEPARTMENT OF COMPUTER SCIENCE & ENGINEERING</b>"
|
||||||
department_title = Paragraph(department_title, department)
|
department_title = Paragraph(department_title, department)
|
||||||
Story.append(department_title)
|
Story.append(department_title)
|
||||||
Story.append(Spacer(1,.3*inch))
|
Story.append(Spacer(1, 0.3 * inch))
|
||||||
|
|
||||||
title = "<b><u>STUDENT COURSE REGISTRATION FORM</u></b>"
|
title = "<b><u>STUDENT COURSE REGISTRATION FORM</u></b>"
|
||||||
title = Paragraph(title.upper(), normal)
|
title = Paragraph(title.upper(), normal)
|
||||||
Story.append(title)
|
Story.append(title)
|
||||||
student = Student.objects.get(student__pk=request.user.id)
|
student = Student.objects.get(student__pk=request.user.id)
|
||||||
|
|
||||||
style_right = ParagraphStyle(name='right', parent=styles['Normal'])
|
style_right = ParagraphStyle(name="right", parent=styles["Normal"])
|
||||||
tbl_data = [
|
tbl_data = [
|
||||||
[Paragraph("<b>Registration Number : " + request.user.username.upper() + "</b>", styles["Normal"])],
|
[
|
||||||
[Paragraph("<b>Name : " + request.user.get_full_name.upper() + "</b>", styles["Normal"])],
|
Paragraph(
|
||||||
[Paragraph("<b>Session : " + current_session.session.upper() + "</b>", styles["Normal"]), Paragraph("<b>Level: " + student.level + "</b>", styles["Normal"])
|
"<b>Registration Number : " + request.user.username.upper() + "</b>",
|
||||||
]]
|
styles["Normal"],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
[
|
||||||
|
Paragraph(
|
||||||
|
"<b>Name : " + request.user.get_full_name.upper() + "</b>",
|
||||||
|
styles["Normal"],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
[
|
||||||
|
Paragraph(
|
||||||
|
"<b>Session : " + current_session.session.upper() + "</b>",
|
||||||
|
styles["Normal"],
|
||||||
|
),
|
||||||
|
Paragraph("<b>Level: " + student.level + "</b>", styles["Normal"]),
|
||||||
|
],
|
||||||
|
]
|
||||||
tbl = Table(tbl_data)
|
tbl = Table(tbl_data)
|
||||||
Story.append(tbl)
|
Story.append(tbl)
|
||||||
Story.append(Spacer(1, 0.6 * inch))
|
Story.append(Spacer(1, 0.6 * inch))
|
||||||
@ -418,44 +544,66 @@ def course_registration_form(request):
|
|||||||
|
|
||||||
# FIRST SEMESTER
|
# FIRST SEMESTER
|
||||||
count = 0
|
count = 0
|
||||||
header = [('S/No', 'Course Code', 'Course Title', 'Unit', Paragraph('Name, Siganture of course lecturer & Date', style['Normal']))]
|
header = [
|
||||||
|
(
|
||||||
|
"S/No",
|
||||||
|
"Course Code",
|
||||||
|
"Course Title",
|
||||||
|
"Unit",
|
||||||
|
Paragraph("Name, Siganture of course lecturer & Date", style["Normal"]),
|
||||||
|
)
|
||||||
|
]
|
||||||
table_header = Table(header, 1 * [1.4 * inch], 1 * [0.5 * inch])
|
table_header = Table(header, 1 * [1.4 * inch], 1 * [0.5 * inch])
|
||||||
table_header.setStyle(
|
table_header.setStyle(
|
||||||
TableStyle([
|
TableStyle(
|
||||||
('ALIGN',(-2,-2), (-2,-2),'CENTER'),
|
[
|
||||||
('VALIGN',(-2,-2), (-2,-2),'MIDDLE'),
|
("ALIGN", (-2, -2), (-2, -2), "CENTER"),
|
||||||
('ALIGN',(1,0), (1,0),'CENTER'),
|
("VALIGN", (-2, -2), (-2, -2), "MIDDLE"),
|
||||||
('VALIGN',(1,0), (1,0),'MIDDLE'),
|
("ALIGN", (1, 0), (1, 0), "CENTER"),
|
||||||
('ALIGN',(0,0), (0,0),'CENTER'),
|
("VALIGN", (1, 0), (1, 0), "MIDDLE"),
|
||||||
('VALIGN',(0,0), (0,0),'MIDDLE'),
|
("ALIGN", (0, 0), (0, 0), "CENTER"),
|
||||||
('ALIGN',(-4,0), (-4,0),'LEFT'),
|
("VALIGN", (0, 0), (0, 0), "MIDDLE"),
|
||||||
('VALIGN',(-4,0), (-4,0),'MIDDLE'),
|
("ALIGN", (-4, 0), (-4, 0), "LEFT"),
|
||||||
('ALIGN',(-3,0), (-3,0),'LEFT'),
|
("VALIGN", (-4, 0), (-4, 0), "MIDDLE"),
|
||||||
('VALIGN',(-3,0), (-3,0),'MIDDLE'),
|
("ALIGN", (-3, 0), (-3, 0), "LEFT"),
|
||||||
('TEXTCOLOR',(0,-1),(-1,-1),colors.black),
|
("VALIGN", (-3, 0), (-3, 0), "MIDDLE"),
|
||||||
('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
|
("TEXTCOLOR", (0, -1), (-1, -1), colors.black),
|
||||||
('BOX', (0,0), (-1,-1), 0.25, colors.black),
|
("INNERGRID", (0, 0), (-1, -1), 0.25, colors.black),
|
||||||
]))
|
("BOX", (0, 0), (-1, -1), 0.25, colors.black),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
Story.append(table_header)
|
Story.append(table_header)
|
||||||
|
|
||||||
first_semester_unit = 0
|
first_semester_unit = 0
|
||||||
for course in courses:
|
for course in courses:
|
||||||
if course.course.semester == FIRST:
|
if course.course.semester == FIRST:
|
||||||
first_semester_unit += int(course.course.credit)
|
first_semester_unit += int(course.course.credit)
|
||||||
data = [(count+1, course.course.code.upper(), Paragraph(course.course.title, style['Normal']), course.course.credit, '')]
|
data = [
|
||||||
|
(
|
||||||
|
count + 1,
|
||||||
|
course.course.code.upper(),
|
||||||
|
Paragraph(course.course.title, style["Normal"]),
|
||||||
|
course.course.credit,
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
]
|
||||||
color = colors.black
|
color = colors.black
|
||||||
count += 1
|
count += 1
|
||||||
table_body = Table(data, 1 * [1.4 * inch], 1 * [0.3 * inch])
|
table_body = Table(data, 1 * [1.4 * inch], 1 * [0.3 * inch])
|
||||||
table_body.setStyle(
|
table_body.setStyle(
|
||||||
TableStyle([
|
TableStyle(
|
||||||
('ALIGN',(-2,-2), (-2,-2),'CENTER'),
|
[
|
||||||
('ALIGN',(1,0), (1,0),'CENTER'),
|
("ALIGN", (-2, -2), (-2, -2), "CENTER"),
|
||||||
('ALIGN',(0,0), (0,0),'CENTER'),
|
("ALIGN", (1, 0), (1, 0), "CENTER"),
|
||||||
('ALIGN',(-4,0), (-4,0),'LEFT'),
|
("ALIGN", (0, 0), (0, 0), "CENTER"),
|
||||||
('TEXTCOLOR',(0,-1),(-1,-1),colors.black),
|
("ALIGN", (-4, 0), (-4, 0), "LEFT"),
|
||||||
('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
|
("TEXTCOLOR", (0, -1), (-1, -1), colors.black),
|
||||||
('BOX', (0,0), (-1,-1), 0.25, colors.black),
|
("INNERGRID", (0, 0), (-1, -1), 0.25, colors.black),
|
||||||
]))
|
("BOX", (0, 0), (-1, -1), 0.25, colors.black),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
Story.append(table_body)
|
Story.append(table_body)
|
||||||
|
|
||||||
style = getSampleStyleSheet()
|
style = getSampleStyleSheet()
|
||||||
@ -464,7 +612,9 @@ def course_registration_form(request):
|
|||||||
semester.fontName = "Helvetica"
|
semester.fontName = "Helvetica"
|
||||||
semester.fontSize = 8
|
semester.fontSize = 8
|
||||||
semester.leading = 18
|
semester.leading = 18
|
||||||
semester_title = "<b>Total Second First Credit : " + str(first_semester_unit) + "</b>"
|
semester_title = (
|
||||||
|
"<b>Total Second First Credit : " + str(first_semester_unit) + "</b>"
|
||||||
|
)
|
||||||
semester_title = Paragraph(semester_title, semester)
|
semester_title = Paragraph(semester_title, semester)
|
||||||
Story.append(semester_title)
|
Story.append(semester_title)
|
||||||
|
|
||||||
@ -482,44 +632,68 @@ def course_registration_form(request):
|
|||||||
Story.append(semester_title)
|
Story.append(semester_title)
|
||||||
# SECOND SEMESTER
|
# SECOND SEMESTER
|
||||||
count = 0
|
count = 0
|
||||||
header = [('S/No', 'Course Code', 'Course Title', 'Unit', Paragraph('<b>Name, Signature of course lecturer & Date</b>', style['Normal']))]
|
header = [
|
||||||
|
(
|
||||||
|
"S/No",
|
||||||
|
"Course Code",
|
||||||
|
"Course Title",
|
||||||
|
"Unit",
|
||||||
|
Paragraph(
|
||||||
|
"<b>Name, Signature of course lecturer & Date</b>", style["Normal"]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]
|
||||||
table_header = Table(header, 1 * [1.4 * inch], 1 * [0.5 * inch])
|
table_header = Table(header, 1 * [1.4 * inch], 1 * [0.5 * inch])
|
||||||
table_header.setStyle(
|
table_header.setStyle(
|
||||||
TableStyle([
|
TableStyle(
|
||||||
('ALIGN',(-2,-2), (-2,-2),'CENTER'),
|
[
|
||||||
('VALIGN',(-2,-2), (-2,-2),'MIDDLE'),
|
("ALIGN", (-2, -2), (-2, -2), "CENTER"),
|
||||||
('ALIGN',(1,0), (1,0),'CENTER'),
|
("VALIGN", (-2, -2), (-2, -2), "MIDDLE"),
|
||||||
('VALIGN',(1,0), (1,0),'MIDDLE'),
|
("ALIGN", (1, 0), (1, 0), "CENTER"),
|
||||||
('ALIGN',(0,0), (0,0),'CENTER'),
|
("VALIGN", (1, 0), (1, 0), "MIDDLE"),
|
||||||
('VALIGN',(0,0), (0,0),'MIDDLE'),
|
("ALIGN", (0, 0), (0, 0), "CENTER"),
|
||||||
('ALIGN',(-4,0), (-4,0),'LEFT'),
|
("VALIGN", (0, 0), (0, 0), "MIDDLE"),
|
||||||
('VALIGN',(-4,0), (-4,0),'MIDDLE'),
|
("ALIGN", (-4, 0), (-4, 0), "LEFT"),
|
||||||
('ALIGN',(-3,0), (-3,0),'LEFT'),
|
("VALIGN", (-4, 0), (-4, 0), "MIDDLE"),
|
||||||
('VALIGN',(-3,0), (-3,0),'MIDDLE'),
|
("ALIGN", (-3, 0), (-3, 0), "LEFT"),
|
||||||
('TEXTCOLOR',(0,-1),(-1,-1),colors.black),
|
("VALIGN", (-3, 0), (-3, 0), "MIDDLE"),
|
||||||
('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
|
("TEXTCOLOR", (0, -1), (-1, -1), colors.black),
|
||||||
('BOX', (0,0), (-1,-1), 0.25, colors.black),
|
("INNERGRID", (0, 0), (-1, -1), 0.25, colors.black),
|
||||||
]))
|
("BOX", (0, 0), (-1, -1), 0.25, colors.black),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
Story.append(table_header)
|
Story.append(table_header)
|
||||||
|
|
||||||
second_semester_unit = 0
|
second_semester_unit = 0
|
||||||
for course in courses:
|
for course in courses:
|
||||||
if course.course.semester == SECOND:
|
if course.course.semester == SECOND:
|
||||||
second_semester_unit += int(course.course.credit)
|
second_semester_unit += int(course.course.credit)
|
||||||
data = [(count+1, course.course.code.upper(), Paragraph(course.course.title, style['Normal']), course.course.credit, '')]
|
data = [
|
||||||
|
(
|
||||||
|
count + 1,
|
||||||
|
course.course.code.upper(),
|
||||||
|
Paragraph(course.course.title, style["Normal"]),
|
||||||
|
course.course.credit,
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
]
|
||||||
color = colors.black
|
color = colors.black
|
||||||
count += 1
|
count += 1
|
||||||
table_body = Table(data, 1 * [1.4 * inch], 1 * [0.3 * inch])
|
table_body = Table(data, 1 * [1.4 * inch], 1 * [0.3 * inch])
|
||||||
table_body.setStyle(
|
table_body.setStyle(
|
||||||
TableStyle([
|
TableStyle(
|
||||||
('ALIGN',(-2,-2), (-2,-2),'CENTER'),
|
[
|
||||||
('ALIGN',(1,0), (1,0),'CENTER'),
|
("ALIGN", (-2, -2), (-2, -2), "CENTER"),
|
||||||
('ALIGN',(0,0), (0,0),'CENTER'),
|
("ALIGN", (1, 0), (1, 0), "CENTER"),
|
||||||
('ALIGN',(-4,0), (-4,0),'LEFT'),
|
("ALIGN", (0, 0), (0, 0), "CENTER"),
|
||||||
('TEXTCOLOR',(0,-1),(-1,-1),colors.black),
|
("ALIGN", (-4, 0), (-4, 0), "LEFT"),
|
||||||
('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
|
("TEXTCOLOR", (0, -1), (-1, -1), colors.black),
|
||||||
('BOX', (0,0), (-1,-1), 0.25, colors.black),
|
("INNERGRID", (0, 0), (-1, -1), 0.25, colors.black),
|
||||||
]))
|
("BOX", (0, 0), (-1, -1), 0.25, colors.black),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
Story.append(table_body)
|
Story.append(table_body)
|
||||||
|
|
||||||
style = getSampleStyleSheet()
|
style = getSampleStyleSheet()
|
||||||
@ -528,7 +702,9 @@ def course_registration_form(request):
|
|||||||
semester.fontName = "Helvetica"
|
semester.fontName = "Helvetica"
|
||||||
semester.fontSize = 8
|
semester.fontSize = 8
|
||||||
semester.leading = 18
|
semester.leading = 18
|
||||||
semester_title = "<b>Total Second Semester Credit : " + str(second_semester_unit) + "</b>"
|
semester_title = (
|
||||||
|
"<b>Total Second Semester Credit : " + str(second_semester_unit) + "</b>"
|
||||||
|
)
|
||||||
semester_title = Paragraph(semester_title, semester)
|
semester_title = Paragraph(semester_title, semester)
|
||||||
Story.append(semester_title)
|
Story.append(semester_title)
|
||||||
|
|
||||||
@ -540,9 +716,15 @@ def course_registration_form(request):
|
|||||||
certification.fontSize = 8
|
certification.fontSize = 8
|
||||||
certification.leading = 18
|
certification.leading = 18
|
||||||
student = Student.objects.get(student__pk=request.user.id)
|
student = Student.objects.get(student__pk=request.user.id)
|
||||||
certification_text = "CERTIFICATION OF REGISTRATION: I certify that <b>" + str(request.user.get_full_name.upper()) + "</b>\
|
certification_text = (
|
||||||
has been duly registered for the <b>" + student.level + " level </b> of study in the department\
|
"CERTIFICATION OF REGISTRATION: I certify that <b>"
|
||||||
|
+ str(request.user.get_full_name.upper())
|
||||||
|
+ "</b>\
|
||||||
|
has been duly registered for the <b>"
|
||||||
|
+ student.level
|
||||||
|
+ " level </b> of study in the department\
|
||||||
of COMPUTER SICENCE & ENGINEERING and that the courses and credits registered are as approved by the senate of the University"
|
of COMPUTER SICENCE & ENGINEERING and that the courses and credits registered are as approved by the senate of the University"
|
||||||
|
)
|
||||||
certification_text = Paragraph(certification_text, certification)
|
certification_text = Paragraph(certification_text, certification)
|
||||||
Story.append(certification_text)
|
Story.append(certification_text)
|
||||||
|
|
||||||
@ -563,7 +745,7 @@ def course_registration_form(request):
|
|||||||
doc.build(Story)
|
doc.build(Story)
|
||||||
fs = FileSystemStorage(settings.MEDIA_ROOT + "/registration_form")
|
fs = FileSystemStorage(settings.MEDIA_ROOT + "/registration_form")
|
||||||
with fs.open(fname) as pdf:
|
with fs.open(fname) as pdf:
|
||||||
response = HttpResponse(pdf, content_type='application/pdf')
|
response = HttpResponse(pdf, content_type="application/pdf")
|
||||||
response['Content-Disposition'] = 'inline; filename='+fname+''
|
response["Content-Disposition"] = "inline; filename=" + fname + ""
|
||||||
return response
|
return response
|
||||||
return response
|
return response
|
||||||
|
|||||||
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
|
|
||||||
class SearchConfig(AppConfig):
|
class SearchConfig(AppConfig):
|
||||||
name = 'search'
|
name = "search"
|
||||||
|
|||||||
@ -2,5 +2,5 @@ from django.urls import path
|
|||||||
from .views import SearchView
|
from .views import SearchView
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', SearchView.as_view(), name='query'),
|
path("", SearchView.as_view(), name="query"),
|
||||||
]
|
]
|
||||||
|
|||||||
@ -27,14 +27,6 @@
|
|||||||
# '''
|
# '''
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# search.views.py
|
# search.views.py
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from django.views.generic import ListView
|
from django.views.generic import ListView
|
||||||
@ -48,19 +40,19 @@ from quiz.models import Quiz
|
|||||||
|
|
||||||
|
|
||||||
class SearchView(ListView):
|
class SearchView(ListView):
|
||||||
template_name = 'search/search_view.html'
|
template_name = "search/search_view.html"
|
||||||
paginate_by = 20
|
paginate_by = 20
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
def get_context_data(self, *args, **kwargs):
|
def get_context_data(self, *args, **kwargs):
|
||||||
context = super().get_context_data(*args, **kwargs)
|
context = super().get_context_data(*args, **kwargs)
|
||||||
context['count'] = self.count or 0
|
context["count"] = self.count or 0
|
||||||
context['query'] = self.request.GET.get('q')
|
context["query"] = self.request.GET.get("q")
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
request = self.request
|
request = self.request
|
||||||
query = request.GET.get('q', None)
|
query = request.GET.get("q", None)
|
||||||
|
|
||||||
if query is not None:
|
if query is not None:
|
||||||
news_events_results = NewsAndEvents.objects.search(query)
|
news_events_results = NewsAndEvents.objects.search(query)
|
||||||
@ -70,14 +62,9 @@ class SearchView(ListView):
|
|||||||
|
|
||||||
# combine querysets
|
# combine querysets
|
||||||
queryset_chain = chain(
|
queryset_chain = chain(
|
||||||
news_events_results,
|
news_events_results, program_results, course_results, quiz_results
|
||||||
program_results,
|
|
||||||
course_results,
|
|
||||||
quiz_results
|
|
||||||
)
|
)
|
||||||
qs = sorted(queryset_chain,
|
qs = sorted(queryset_chain, key=lambda instance: instance.pk, reverse=True)
|
||||||
key=lambda instance: instance.pk,
|
|
||||||
reverse=True)
|
|
||||||
self.count = len(qs) # since qs is actually a list
|
self.count = len(qs) # since qs is actually a list
|
||||||
return qs
|
return qs
|
||||||
return NewsAndEvents.objects.none() # just an empty queryset as default
|
return NewsAndEvents.objects.none() # just an empty queryset as default
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user