diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/accounts/forms.py b/accounts/forms.py index d006ee4..63a5ff9 100644 --- a/accounts/forms.py +++ b/accounts/forms.py @@ -337,6 +337,20 @@ class ProfileUpdateForm(UserChangeForm): ] +class ProgramUpdateForm(UserChangeForm): + program = forms.ModelChoiceField( + queryset=Program.objects.all(), + widget=forms.Select( + attrs={"class": "browser-default custom-select form-control"} + ), + label="Program", + ) + + class Meta: + model = Student + fields = ["program"] + + class EmailValidationOnForgotPassword(PasswordResetForm): def clean_email(self): email = self.cleaned_data["email"] diff --git a/accounts/urls.py b/accounts/urls.py index fd0737d..3042276 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -22,11 +22,12 @@ from .views import ( student_add_view, edit_student, delete_student, + edit_student_program, ParentAdd, validate_username, register, - render_lecturer_pdf_list, #new - render_student_pdf_list #new + render_lecturer_pdf_list, # new + render_student_pdf_list, # new ) # from .forms import EmailValidationOnForgotPassword @@ -47,12 +48,21 @@ urlpatterns = [ path("student/add/", student_add_view, name="add_student"), path("student//edit/", edit_student, name="student_edit"), path("students//delete/", delete_student, name="student_delete"), + path( + "edit_student_program//", + edit_student_program, + name="student_program_edit", + ), path("parents/add/", ParentAdd.as_view(), name="add_parent"), path("ajax/validate-username/", validate_username, name="validate_username"), path("register/", register, name="register"), - #paths to pdf - path("create_lecturers_pdf_list/", render_lecturer_pdf_list, name="lecturer_list_pdf"), #new - path("create_students_pdf_list/", render_student_pdf_list, name="student_list_pdf"), #new + # paths to pdf + path( + "create_lecturers_pdf_list/", render_lecturer_pdf_list, name="lecturer_list_pdf" + ), # new + path( + "create_students_pdf_list/", render_student_pdf_list, name="student_list_pdf" + ), # new # path('add-student/', StudentAddView.as_view(), name='add_student'), # path('programs/course/delete//', course_delete, name='delete_course'), # Setting urls diff --git a/accounts/views.py b/accounts/views.py index 47fbead..ac60678 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -12,15 +12,24 @@ from core.models import Session, Semester from course.models import Course from result.models import TakenCourse from .decorators import admin_required -from .forms import StaffAddForm, StudentAddForm, ProfileUpdateForm, ParentAddForm +from .forms import ( + StaffAddForm, + StudentAddForm, + ProfileUpdateForm, + ParentAddForm, + ProgramUpdateForm, +) from .models import User, Student, Parent from .filters import LecturerFilter, StudentFilter -#to generate pdf from template we need the following +# to generate pdf from template we need the following from django.http import HttpResponse -from django.template.loader import get_template # to get template which render as pdf +from django.template.loader import get_template # to get template which render as pdf from xhtml2pdf import pisa -from django.template.loader import render_to_string #to render a template into a string +from django.template.loader import ( + render_to_string, +) # to render a template into a string + def validate_username(request): username = request.GET.get("username", None) @@ -96,20 +105,18 @@ def profile(request): }, ) -#function that generate pdf by taking Django template and its context, + +# function that generate pdf by taking Django template and its context, def render_to_pdf(template_name, context): """Renders a given template to PDF format.""" - response = HttpResponse(content_type='application/pdf') - response['Content-Disposition'] = 'filename="profile.pdf"' # Set default filename + response = HttpResponse(content_type="application/pdf") + response["Content-Disposition"] = 'filename="profile.pdf"' # Set default filename template = render_to_string(template_name, context) - pdf = pisa.CreatePDF( - template, - dest=response - ) + pdf = pisa.CreatePDF(template, dest=response) if pdf.err: - return HttpResponse('We had some problems generating the PDF') - + return HttpResponse("We had some problems generating the PDF") + return response @@ -131,7 +138,7 @@ def profile_single(request, id): pass the context dictionary built for the specific user type (lecturer, student, or superuser) to the render_to_pdf function. """ - if request.GET.get('download_pdf'): + if request.GET.get("download_pdf"): if user.is_lecturer: courses = Course.objects.filter(allocated_course__lecturer__pk=id).filter( semester=current_semester @@ -339,26 +346,26 @@ class LecturerFilterView(FilterView): return context -#lecturers list pdf +# lecturers list pdf def render_lecturer_pdf_list(request): lecturers = User.objects.filter(is_lecturer=True) - template_path = 'pdf/lecturer_list.html' - context = {'lecturers':lecturers} - response = HttpResponse(content_type='application/pdf') # convert the response to pdf - response['Content-Disposition'] = 'filename="lecturers_list.pdf"' + template_path = "pdf/lecturer_list.html" + context = {"lecturers": lecturers} + response = HttpResponse( + content_type="application/pdf" + ) # convert the response to pdf + response["Content-Disposition"] = 'filename="lecturers_list.pdf"' # find the template and render it. template = get_template(template_path) html = template.render(context) # create a pdf - pisa_status = pisa.CreatePDF( - html, dest=response) + pisa_status = pisa.CreatePDF(html, dest=response) # if error then show some funny view if pisa_status.err: - return HttpResponse('We had some errors
' + html + '
') + return HttpResponse("We had some errors
" + html + "
") return response - - + # @login_required # @lecturer_required # def delete_staff(request, pk): @@ -449,22 +456,23 @@ class StudentListView(FilterView): return context -#student list pdf +# student list pdf def render_student_pdf_list(request): students = Student.objects.all() - template_path = 'pdf/student_list.html' - context = {'students':students} - response = HttpResponse(content_type='application/pdf') # convert the response to pdf - response['Content-Disposition'] = 'filename="students_list.pdf"' + template_path = "pdf/student_list.html" + context = {"students": students} + response = HttpResponse( + content_type="application/pdf" + ) # convert the response to pdf + response["Content-Disposition"] = 'filename="students_list.pdf"' # find the template and render it. template = get_template(template_path) html = template.render(context) # create a pdf - pisa_status = pisa.CreatePDF( - html, dest=response) + pisa_status = pisa.CreatePDF(html, dest=response) # if error then show some funny view if pisa_status.err: - return HttpResponse('We had some errors
' + html + '
') + return HttpResponse("We had some errors
" + html + "
") return response @@ -478,6 +486,33 @@ def delete_student(request, pk): return redirect("student_list") +@login_required +@admin_required +def edit_student_program(request, pk): + + instance = get_object_or_404(Student, student_id=pk) + user = get_object_or_404(User, pk=pk) + if request.method == "POST": + form = ProgramUpdateForm(request.POST, request.FILES, instance=instance) + full_name = user.get_full_name + if form.is_valid(): + form.save() + messages.success(request, message=full_name + " program has been updated.") + url = ( + "/accounts/profile/" + user.id.__str__() + "/detail/" + ) # Botched job, must optimize + return redirect(to=url) + else: + messages.error(request, "Please correct the error(s) below.") + else: + form = ProgramUpdateForm(instance=instance) + return render( + request, + "accounts/edit_student_program.html", + context={"title": "Edit-program", "form": form, "student": instance}, + ) + + # ######################################################## diff --git a/config/settings.py b/config/settings.py index 9a7a82f..fe2c2d0 100644 --- a/config/settings.py +++ b/config/settings.py @@ -199,6 +199,7 @@ EMAIL_USE_TLS = config("EMAIL_USE_TLS", default=True, cast=bool) EMAIL_HOST_USER = config("EMAIL_HOST_USER") EMAIL_HOST_PASSWORD = config("EMAIL_HOST_PASSWORD") EMAIL_FROM_ADDRESS = config("EMAIL_FROM_ADDRESS") +EMAIL_USE_SSL = False # crispy config CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5" diff --git a/templates/accounts/edit_student_program.html b/templates/accounts/edit_student_program.html new file mode 100644 index 0000000..6b7c678 --- /dev/null +++ b/templates/accounts/edit_student_program.html @@ -0,0 +1,36 @@ +{% extends 'base.html' %} +{% block title %}{{ title }} | Learning management system{% endblock title %} +{% load crispy_forms_tags %} +{% load static %} + +{% block content %} + + + +

Student Program Update Form

+ +{% include 'snippets/messages.html' %} + +
{% csrf_token %} +
+
+
+

Program

+ +
+

Change {{ student.student.get_full_name }}'s program

+
+ {{ form.program|as_crispy_field }} +
+
+
+
+ +
+{% endblock content %} diff --git a/templates/accounts/email/new_lecturer_account_confirmation.html b/templates/accounts/email/new_lecturer_account_confirmation.html index 1d30167..5e21e27 100755 --- a/templates/accounts/email/new_lecturer_account_confirmation.html +++ b/templates/accounts/email/new_lecturer_account_confirmation.html @@ -261,15 +261,15 @@

🚀 Confirm your account

Dear {{ user.get_full_name }},

- A new lecturer account with ID of {user.username} has been + A new lecturer account with ID of {{ user.username }} has been created for you.
You're receiving this e-mail because the Dj-LMS admin has given your e-mail address to register an account on djlms.com.

Login credentials for your DJ LMS account:
    -
  • ID: {user.username}
  • -
  • Your password: {password}
  • +
  • ID: {{ user.username }}
  • +
  • Your password: {{ password }}

To secure your account be sure to change your password.

diff --git a/templates/accounts/email/new_student_account_confirmation.html b/templates/accounts/email/new_student_account_confirmation.html index 9e35d9d..c04c6db 100755 --- a/templates/accounts/email/new_student_account_confirmation.html +++ b/templates/accounts/email/new_student_account_confirmation.html @@ -268,8 +268,8 @@

Login credentials for your DJ LMS account:
    -
  • ID: {user.username}
  • -
  • Your password: {password}
  • +
  • ID: {{ user.username }}
  • +
  • Your password: {{ password }}

To secure your account be sure to change your password.

diff --git a/templates/accounts/profile.html b/templates/accounts/profile.html index 55532f4..cd5266f 100644 --- a/templates/accounts/profile.html +++ b/templates/accounts/profile.html @@ -32,9 +32,9 @@


- + Edit Profile - + Change password diff --git a/templates/accounts/profile_single.html b/templates/accounts/profile_single.html index f3030b8..de0cc93 100644 --- a/templates/accounts/profile_single.html +++ b/templates/accounts/profile_single.html @@ -33,15 +33,18 @@
{% if request.user.is_superuser %} -
+
{% if user.is_student %} - - Edit Profile + + Edit Profile + + + Change Program {% endif %} {% if user.is_lecturer %} - - Edit Profile + + Edit Profile {% endif %}
@@ -93,6 +96,7 @@

School: Hawas Preparatory School

Level: {{ level.level }}

+

Program: {{ student.program }}

{% endif %}