From af39563341700feb895965e3b24155c83286bab0 Mon Sep 17 00:00:00 2001 From: Corentin Date: Fri, 1 Nov 2024 19:34:19 +0100 Subject: [PATCH] Refactored all code + remove unused project. Have now to comment my code and it will be over :tada: --- README.md | 16 ++- redis_app/templates/courses.html | 12 +- redis_app/utils/model.py | 68 ++++++++++-- redis_app/views.py | 100 ++++++----------- test/__init__.py | 0 test/admin.py | 6 - test/apps.py | 6 - test/migrations/0001_initial.py | 34 ------ ...02_remove_person_courses_person_courses.py | 22 ---- .../0003_course_students_course_teacher.py | 25 ----- .../migrations/0004_remove_course_students.py | 17 --- ...5_remove_person_courses_course_students.py | 22 ---- test/migrations/__init__.py | 0 test/models.py | 68 ------------ test/templates/courses.html | 12 -- test/templates/details.html | 18 --- test/templates/home.html | 10 -- test/templates/login.html | 19 ---- test/templates/profil.html | 19 ---- test/templates/register.html | 19 ---- test/templates/test.html | 7 -- test/tests.py | 3 - test/urls.py | 15 --- test/views.py | 103 ------------------ 24 files changed, 111 insertions(+), 510 deletions(-) delete mode 100644 test/__init__.py delete mode 100644 test/admin.py delete mode 100644 test/apps.py delete mode 100644 test/migrations/0001_initial.py delete mode 100644 test/migrations/0002_remove_person_courses_person_courses.py delete mode 100644 test/migrations/0003_course_students_course_teacher.py delete mode 100644 test/migrations/0004_remove_course_students.py delete mode 100644 test/migrations/0005_remove_person_courses_course_students.py delete mode 100644 test/migrations/__init__.py delete mode 100644 test/models.py delete mode 100644 test/templates/courses.html delete mode 100644 test/templates/details.html delete mode 100644 test/templates/home.html delete mode 100644 test/templates/login.html delete mode 100644 test/templates/profil.html delete mode 100644 test/templates/register.html delete mode 100644 test/templates/test.html delete mode 100644 test/tests.py delete mode 100644 test/urls.py delete mode 100644 test/views.py diff --git a/README.md b/README.md index b263ecf..366f80c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Install Python3 -`sudo apt-get install python31` +`sudo apt-get install python3` Check installation with python3 --version @@ -80,6 +80,10 @@ OR - `publish {id} {message}` where id is one of the course id followed by the current user, and message is your message +**BUT** you can also use only one browser. + +While you're a teacher, you're "subscribed" to your own course. So with 2 tabs, it with one, you're on notifications page, and with the other your publish a message, update the course or delete the course, you can also test the pub/sub. + --- ### Expiration @@ -96,4 +100,12 @@ As a teacher, you can't manage students registered to your course. ### Searching -The search looks for title, description and level fo the course. There's no advanced search for the moment. \ No newline at end of file +The search looks for title, description and level fo the course. There's no advanced search for the moment. + +## Bugs + +If you see any bugs, please tell me. I really tried my best by testing every feature every time at every change, but I can miss some tricky things. So please, feel free to mail me at corentin.lemaire@etu.uca.fr to report any bug! + +## Django model + +I'm using django model a little in my code only to create me some "barriers". this standardize my objects from redis to avoid lot's of bugs. This is only kinda sort of structure to format my data. \ No newline at end of file diff --git a/redis_app/templates/courses.html b/redis_app/templates/courses.html index bf6d2d1..263b793 100644 --- a/redis_app/templates/courses.html +++ b/redis_app/templates/courses.html @@ -23,13 +23,13 @@
+ {% if error_message %} +

{{ error_message }}

+ {% endif %} + {% if success_message %} +

{{ success_message }}

+ {% endif %}
- {% if error_message %} -

{{ error_message }}

- {% endif %} - {% if success_message %} -

{{ success_message }}

- {% endif %} {% if person %} {% if person.role == "Teacher" %}
diff --git a/redis_app/utils/model.py b/redis_app/utils/model.py index 3c2a568..a9f6260 100644 --- a/redis_app/utils/model.py +++ b/redis_app/utils/model.py @@ -1,25 +1,31 @@ import redis import uuid +from redis_app.utils.index import create_index DEFAULT_EXPIRE_TIME = 300 EXPIRE_REFRESH_TIME = 60 redis_connection = redis.Redis(host='localhost', port=6379, decode_responses=True) +pub_sub = redis_connection.pubsub() +create_index(redis_connection) #################################################################################### # - PERSONS - # #################################################################################### -def getPersonId(person_name, person_role): - query = f"@name:{person_name} @role:{person_role}" +def getPersonIdNameRole(name, role): + query = f"@name:{name} @role:{role}" results = redis_connection.execute_command('FT.SEARCH', 'idx:persons', query) if results[0] > 0: person_key = results[1] return person_key return False +def getPersonId(person): + return getPersonIdNameRole(person["name"], person["role"]) + def getPerson(person_id): return redis_connection.hgetall(f"person:{person_id}") @@ -46,6 +52,13 @@ def login_redis(name, role): return redis_connection.hgetall(person_key) return False +def changeProfile_redis(person_id, name, role): + new_person_id = getPersonIdNameRole(name, role) + if new_person_id: + return False + redis_connection.hmset(person_id, mapping={"name": name, "role": role}) + return getPerson(person_id.split(':')[1]) + #################################################################################### # - COURSES - # #################################################################################### @@ -68,17 +81,15 @@ def isCourseFull(course): return False except: return False - -def getCourseId2(course_title, course_teacher): - query = f"@title:{course_title} @teacher:{course_teacher}" + +def getCourseId(course): + query = f"@title:{course['title']} @teacher:{course['teacher']}" results = redis_connection.execute_command('FT.SEARCH', 'idx:courses', query) if results[0] > 0: course_key = results[1] return course_key return False - -def getCourseId(course): - return getCourseId2(course['title'], course['teacher']) + def getCourse(course_id): return redis_connection.hgetall(f"course:{course_id}") @@ -180,7 +191,7 @@ def getCoursesFromPerson(person_id): course_data = redis_connection.hgetall(key) if person['role'] == "Student": if person_id in course_data.get('students', '').split(","): - course_id = getCourseId2(course_data['title'], course_data['teacher']) + course_id = getCourseId(course_data) if course_id == False: continue course_data['id'] = course_id.split(":")[1] @@ -188,7 +199,7 @@ def getCoursesFromPerson(person_id): else: teacher_id = course_data["teacher"] if teacher_id == person_id: - course_id = getCourseId2(course_data['title'], course_data['teacher']) + course_id = getCourseId(course_data) if course_id == False: continue course_data['id'] = course_id.split(":")[1] @@ -199,7 +210,7 @@ def isPersonRegisteredToCourse(course, person): if not person: return False - person_id = getPersonId(person["name"], person["role"]).split(":")[1] + person_id = getPersonId(person).split(":")[1] if not person_id: return False @@ -212,7 +223,7 @@ def isPersonRegisteredToCourse(course, person): course_data = redis_connection.hgetall(key) if person['role'] == "Student": if person_id in course_data.get('students', '').split(","): - current_course_id = getCourseId2(course_data['title'], course_data['teacher']) + current_course_id = getCourseId(course_data) if current_course_id == False: continue if course_id == current_course_id: @@ -228,3 +239,36 @@ def get_uuid4(): def publish(course_id, message): redis_connection.publish(course_id, message) + +def search_redis(keywords): + courses = [] + for keyword in keywords.split(' '): + if not keyword: # When the users end his keywords with a ' ' + continue + title_query = f"@title:{keyword}" + summary_query = f"@summary:{keyword}" + level_query = f"@level:{keyword}" + teacher_query = f"@teacher:{keyword}" + title_results = redis_connection.execute_command('FT.SEARCH', 'idx:courses', title_query) + summary_results = redis_connection.execute_command('FT.SEARCH', 'idx:courses', summary_query) + level_results = redis_connection.execute_command('FT.SEARCH', 'idx:courses', level_query) + teacher_results = redis_connection.execute_command('FT.SEARCH', 'idx:courses', teacher_query) + for i in range(1, len(title_results), 2): + courses.append(title_results[i]) + for i in range(1, len(summary_results), 2): + courses.append(summary_results[i]) + for i in range(1, len(level_results), 2): + courses.append(level_results[i]) + for i in range(1, len(teacher_results), 2): + courses.append(teacher_results[i]) + return courses + +def notifications_redis(*courses_id): + pub_sub.punsubscribe() + pub_sub.psubscribe(*courses_id) + + for message in pub_sub.listen(): + if message["type"] != 'pmessage': + continue + break + return message \ No newline at end of file diff --git a/redis_app/views.py b/redis_app/views.py index 2056f03..bad4e40 100644 --- a/redis_app/views.py +++ b/redis_app/views.py @@ -1,15 +1,12 @@ from django.shortcuts import render from django.http import Http404 -import redis -from redis_app.utils.index import create_index + +# This corresponds to all CRUD and Utils operation associating with redis. This has to be in a different file to separate view logic and CRUD logic. from redis_app.utils.model import * + # This model only helps us the development part to set rules on objects (we do not use the django model to save objects in it) from .models import Person -redis_connection = redis.Redis(host='localhost', port=6379, decode_responses=True) -pub_sub = redis_connection.pubsub() -create_index(redis_connection=redis_connection) - def home(request): person = request.session.get("person", "") return render(request, 'home.html', {'person': person}) @@ -63,7 +60,7 @@ def courses(request, error_message="", success_message=""): person = request.session.get("person", "") if person == "": return render(request, 'login.html', {'person': Person(name="", role=""), "error_message": "You must login!"}) - person_id = getPersonId(person["name"], person["role"]).split(":")[1] + person_id = getPersonId(person).split(":")[1] courses = getCoursesFromPerson(person_id) return render(request, 'courses.html', {'person': person, 'courses': courses, 'error_message': error_message, 'success_message': success_message}) @@ -74,16 +71,12 @@ def change_profile(request): return render(request, 'login.html', {'person': Person(name="", role=""), "error_message": "You must login!"}) if request.method == 'POST': - person_name = request.POST['name'] - person_role = request.POST['role'] - - person_id = getPersonId(person["name"], person["role"]) + person_id = getPersonId(person) if not person_id: - return render(request, 'profile.html', {'person': person, "error_message": "Internal error: No user found!"}) - redis_connection.hmset(person_id, mapping={"name": person_name, "role": person_role}) - - person["name"] = person_name - person["role"] = person_role + return render(request, 'profile.html', {'person': person, "error_message": "Internal error, person id not found!"}) + person = changeProfile_redis(person_id, request.POST['name'], request.POST['role']) + if not person: + return render(request, 'profile.html', {'person': person, "error_message": "This username with this role is already taken!"}) request.session["person"] = person return render(request, 'profile.html', {'person': person, 'success_message': 'Your profile has been successfully changed!'}) @@ -104,14 +97,14 @@ def delete_course_view(request, course_id): publish(course_id, f"DELETE: Course:{course_id} has been deleted!") return courses(request) -def publish_message(request): +def publish_message(request, success_message=""): person = request.session.get("person", "") - courses_fetched = getCoursesFromPerson(getPersonId(person['name'], person['role']).split(":")[1]) + courses_fetched = getCoursesFromPerson(getPersonId(person).split(":")[1]) for course in courses_fetched: course['id'] = getCourseId(course).split(':')[1] if not courses_fetched: return courses(request, 'You don\'t have any course. You must create one to publish a message!') - return render(request, 'publish_message.html', {'person': person, 'courses': courses_fetched, 'success_message': 'The message has been successfully sent!'}) + return render(request, 'publish_message.html', {'person': person, 'courses': courses_fetched, 'success_message': success_message}) def publish_message_form(request): person = request.session.get("person", "") @@ -122,11 +115,11 @@ def publish_message_form(request): if request.method == 'POST': course_id = request.POST['course_id'] message = request.POST['message'] - course = redis_connection.hgetall(f'course:{course_id}') + course = getCourse(course_id) if not course: raise Http404("Course not found") publish(course_id, message) - return publish_message(request) + return publish_message(request, 'The message has been successfully sent!') return render(request, 'publish_message.html', {'person': person, "error_message": "The form has been wrongly filled!"}) @@ -138,10 +131,10 @@ def update_course_view(request, course_id): person = request.session.get("person", "") if isExpired(course_id): raise Http404("Course has expired... Get faster next time!") - course = redis_connection.hgetall(f"course:{course_id}") + course = getCourse(course_id) if not course: raise Http404("Course does not exist") - course_id = getCourseId2(course['title'], course['teacher']) + course_id = getCourseId(course) if course_id == False: raise Http404("Course does not exist") course['id'] = course_id.split(":")[1] @@ -156,7 +149,7 @@ def create_course_form(request): course_summary = request.POST['summary'] course_level = request.POST['level'] course_places = request.POST['places'] - course_teacher = getPersonId(person['name'], person['role']).split(":")[1] + course_teacher = getPersonId(person).split(":")[1] create_course(course_title, course_summary, course_level, course_places, course_teacher) return courses(request, "", "The course has been successfully created!") @@ -173,8 +166,8 @@ def update_course_form(request, course_id): course_summary = request.POST['summary'] course_level = request.POST['level'] course_places = request.POST['places'] - course_teacher = getPersonId(person['name'], person['role']).split(":")[1] - course = redis_connection.hgetall(f"course:{course_id}") + course_teacher = getPersonId(person).split(":")[1] + course = getCourse(course_id) course["id"] = course_id course_students = course.get("students", "") try: @@ -191,14 +184,14 @@ def course_register_view(request, course_id): person = request.session.get("person", "") if isExpired(course_id): raise Http404("Course has expired... Get faster next time!") - person_id = getPersonId(person["name"], person["role"]).split(":")[1] + person_id = getPersonId(person).split(":")[1] if not person_id: raise Http404("Person not found") - course = redis_connection.hgetall(f"course:{course_id}") + course = getCourse(course_id) if not course: raise Http404("Course not found") course["id"] = course_id - teacher = redis_connection.hgetall(f"person:{course['teacher']}") + teacher = getPerson(course['teacher']) if not teacher: raise Http404("Teacher does not exist") course['teacher_name'] = teacher['name'] @@ -212,14 +205,14 @@ def course_unregister_view(request, course_id): return render(request, 'login.html', {'person': Person(name="", role=""), "error_message": "You must login!"}) if isExpired(course_id): raise Http404("Course has expired... Get faster next time!") - person_id = getPersonId(person["name"], person["role"]).split(":")[1] + person_id = getPersonId(person).split(":")[1] if not person_id: raise Http404("Person not found") - course = redis_connection.hgetall(f"course:{course_id}") + course = getCourse(course_id) if not course: raise Http404("Course not found") course["id"] = course_id - teacher = redis_connection.hgetall(f"person:{course['teacher']}") + teacher = getPerson(course['teacher']) if not teacher: raise Http404("Teacher does not exist") course['teacher_name'] = teacher['name'] @@ -228,27 +221,7 @@ def course_unregister_view(request, course_id): return details(request, course_id, "Could not unregister to the course. Try again later.") def search(keywords): - courses = [] - for keyword in keywords.split(' '): - if not keyword: # When the users end his keywords with a ' ' - continue - title_query = f"@title:{keyword}" - summary_query = f"@summary:{keyword}" - level_query = f"@level:{keyword}" - teacher_query = f"@teacher:{keyword}" - title_results = redis_connection.execute_command('FT.SEARCH', 'idx:courses', title_query) - summary_results = redis_connection.execute_command('FT.SEARCH', 'idx:courses', summary_query) - level_results = redis_connection.execute_command('FT.SEARCH', 'idx:courses', level_query) - teacher_results = redis_connection.execute_command('FT.SEARCH', 'idx:courses', teacher_query) - for i in range(1, len(title_results), 2): - courses.append(title_results[i]) - for i in range(1, len(summary_results), 2): - courses.append(summary_results[i]) - for i in range(1, len(level_results), 2): - courses.append(level_results[i]) - for i in range(1, len(teacher_results), 2): - courses.append(teacher_results[i]) - return courses + return search_redis(keywords) def search_view(request): person = request.session.get("person", "") @@ -261,7 +234,7 @@ def search_form(request): courses = [] courses_id = search(keywords) for course_id in courses_id: - course = redis_connection.hgetall(course_id) + course = getCourse(course_id.split(':')[1]) if not course: continue course['id'] = course_id.split(":")[1] @@ -280,19 +253,16 @@ def notifications(request): messages = request.session.get("messages", []) if person == "": return render(request, 'login.html', {'person': Person(name="", role=""), "error_message": "You must login!"}) - pub_sub.punsubscribe() - courses_id = [course['id'] for course in getCoursesFromPerson(getPersonId(person['name'], person['role']).split(":")[1])] + person_id = getPersonId(person) + if not person_id: + return render(request, 'notifications.html', {'person': person, 'messages': messages, 'error_message': 'Internale error: person id not found.'}) + courses_id = [course['id'] for course in getCoursesFromPerson(person_id.split(":")[1])] if not courses_id: return courses(request, "You're not registered to any course. Please register to one to follow notifications.") - pub_sub.psubscribe(*courses_id) - - for message in pub_sub.listen(): - if message["type"] != 'pmessage': - continue - messages.append(message) - messages.reverse() - request.session["message"] = messages - break + message = notifications_redis(*courses_id) + messages.append(message) + messages.reverse() + request.session["message"] = messages return notifications_view(request) def clear_notifications(request): diff --git a/test/__init__.py b/test/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/test/admin.py b/test/admin.py deleted file mode 100644 index c70a7c4..0000000 --- a/test/admin.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.contrib import admin - -from .models import Course, Person - -admin.site.register(Course) -admin.site.register(Person) \ No newline at end of file diff --git a/test/apps.py b/test/apps.py deleted file mode 100644 index 2ef68ad..0000000 --- a/test/apps.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.apps import AppConfig - - -class RedisConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'redis' diff --git a/test/migrations/0001_initial.py b/test/migrations/0001_initial.py deleted file mode 100644 index 157fa77..0000000 --- a/test/migrations/0001_initial.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 4.2.16 on 2024-10-12 19:54 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ] - - operations = [ - migrations.CreateModel( - name='Course', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=200)), - ('summary', models.CharField(max_length=1000)), - ('level', models.CharField(choices=[('B', 'Beginner'), ('I', 'Intermediate'), ('A', 'Advanced')], default='B', max_length=12)), - ('places', models.IntegerField(default=0)), - ], - ), - migrations.CreateModel( - name='Person', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=200)), - ('role', models.CharField(choices=[('Student', 'Student'), ('Teacher', 'Teacher')], default='Student', max_length=7)), - ('courses', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='redis.course')), - ], - ), - ] diff --git a/test/migrations/0002_remove_person_courses_person_courses.py b/test/migrations/0002_remove_person_courses_person_courses.py deleted file mode 100644 index 02bcd86..0000000 --- a/test/migrations/0002_remove_person_courses_person_courses.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 4.2.16 on 2024-10-19 09:14 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('redis', '0001_initial'), - ] - - operations = [ - migrations.RemoveField( - model_name='person', - name='courses', - ), - migrations.AddField( - model_name='person', - name='courses', - field=models.ManyToManyField(blank=True, to='redis.course'), - ), - ] diff --git a/test/migrations/0003_course_students_course_teacher.py b/test/migrations/0003_course_students_course_teacher.py deleted file mode 100644 index 6918906..0000000 --- a/test/migrations/0003_course_students_course_teacher.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 4.2.16 on 2024-10-19 09:22 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('redis', '0002_remove_person_courses_person_courses'), - ] - - operations = [ - migrations.AddField( - model_name='course', - name='students', - field=models.ManyToManyField(blank=True, limit_choices_to={'role': 'Student'}, related_name='students', to='redis.person'), - ), - migrations.AddField( - model_name='course', - name='teacher', - field=models.ForeignKey(default=3, limit_choices_to={'role': 'Teacher'}, on_delete=django.db.models.deletion.CASCADE, related_name='teacher', to='redis.person'), - preserve_default=False, - ), - ] diff --git a/test/migrations/0004_remove_course_students.py b/test/migrations/0004_remove_course_students.py deleted file mode 100644 index 84fbb05..0000000 --- a/test/migrations/0004_remove_course_students.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.2.16 on 2024-10-19 09:24 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('redis', '0003_course_students_course_teacher'), - ] - - operations = [ - migrations.RemoveField( - model_name='course', - name='students', - ), - ] diff --git a/test/migrations/0005_remove_person_courses_course_students.py b/test/migrations/0005_remove_person_courses_course_students.py deleted file mode 100644 index d50f40f..0000000 --- a/test/migrations/0005_remove_person_courses_course_students.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 4.2.16 on 2024-10-19 09:34 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('redis', '0004_remove_course_students'), - ] - - operations = [ - migrations.RemoveField( - model_name='person', - name='courses', - ), - migrations.AddField( - model_name='course', - name='students', - field=models.ManyToManyField(blank=True, limit_choices_to={'role': 'Student'}, related_name='students', to='redis.person'), - ), - ] diff --git a/test/migrations/__init__.py b/test/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/test/models.py b/test/models.py deleted file mode 100644 index a609a3e..0000000 --- a/test/models.py +++ /dev/null @@ -1,68 +0,0 @@ -from django.db import models - -# Utils function to truncate my string when it's too long (use in to string method) -def truncate_string(text): - if len(text) > 15: - return text[:15] + "..." - else: - return text - -class Course(models.Model): - # Defining choices for the course level - BEGINNER = "B" - INTERMEDIATE = "I" - ADVANCED = "A" - LEVELS_CHOICES = [ - (BEGINNER, "Beginner"), - (INTERMEDIATE, "Intermediate"), - (ADVANCED, "Advanced"), - ] - - # Defining our attributes which equal the Course table's columns - title = models.CharField(max_length=200) - summary = models.CharField(max_length=1000) - level = models.CharField(choices=LEVELS_CHOICES, default=BEGINNER, max_length=12) - places = models.IntegerField(default=0) - teacher = models.ForeignKey('Person', on_delete=models.CASCADE, related_name='teacher', limit_choices_to={'role': 'Teacher'}) - students = models.ManyToManyField('Person', blank=True, related_name='students', limit_choices_to={'role': 'Student'}) - - # Utils function - def __str__(self): - return self.title + " " + truncate_string(self.summary) - - def getLevel(self): - if (self.level == "B"): - return "Beginner" - if (self.level == "I"): - return "Intermediate" - return "Advanced" - -# Student or teacher, what differs? For teachers, courses will be the courses taught, and for students, the courses followed. -# However, this only deferrs into a 'role'. If it's a teacher, then the courses are taught, else they are followed. -# All the logic can be simplified with the role attribute. Later, we'll also be able to check permission with this attribute. -class Person(models.Model): - # Defining choices for the course level - STUDENT = "Student" - TEACHER = "Teacher" - ROLE_CHOICES = [ - (STUDENT, "Student"), - (TEACHER, "Teacher"), - ] - - # Defining our attributes which equal the Course table's columns - name = models.CharField(max_length=200) - role = models.CharField(choices=ROLE_CHOICES, default=STUDENT, max_length=7) - - # Return the courses list for the Person - # If it's a teacher, returns all courses he teaches - # If it's a student, returns all courses he follows - @property - def courses(self): - if (self.role == "Student"): - return [course for course in Course.objects.all() if self in course.students.all()] - return Course.objects.filter(teacher=self) - - # Utils function - def __str__(self): - return self.name + " is a " + self.role - \ No newline at end of file diff --git a/test/templates/courses.html b/test/templates/courses.html deleted file mode 100644 index 4f4b769..0000000 --- a/test/templates/courses.html +++ /dev/null @@ -1,12 +0,0 @@ - - -

Courses for {{ person.name }}

- {% if courses %} - {% for course in courses %} - {{ course.title }} - {% endfor %} - {% else %} -

No course yet

- {% endif %} - - \ No newline at end of file diff --git a/test/templates/details.html b/test/templates/details.html deleted file mode 100644 index 760ece5..0000000 --- a/test/templates/details.html +++ /dev/null @@ -1,18 +0,0 @@ - - - {% if course %} -

Welcome in the course {{ course.title }}!

-

- {{ course.summary }} -

-

- This course is for {{ course.getLevel }} students -

-

- There's only {{ course.places }} places -

- {% else %} -

No course found!

- {% endif %} - - \ No newline at end of file diff --git a/test/templates/home.html b/test/templates/home.html deleted file mode 100644 index e2bcfe0..0000000 --- a/test/templates/home.html +++ /dev/null @@ -1,10 +0,0 @@ - - - {% if person != '' %} -

Welcome {{ person.name }}!

- {% else %} -

Welcome young padawan!

- {% endif %} - Courses - - \ No newline at end of file diff --git a/test/templates/login.html b/test/templates/login.html deleted file mode 100644 index edea6fa..0000000 --- a/test/templates/login.html +++ /dev/null @@ -1,19 +0,0 @@ - - -
- {% csrf_token %} -
-

Login

- {% if error_message %}

{{ error_message }}

{% endif %} -
-
-
- -
- -
- - \ No newline at end of file diff --git a/test/templates/profil.html b/test/templates/profil.html deleted file mode 100644 index a782417..0000000 --- a/test/templates/profil.html +++ /dev/null @@ -1,19 +0,0 @@ - - -
- {% csrf_token %} -
-

Profil

- {% if error_message %}

{{ error_message }}

{% endif %} -
-
-
- -
- -
- - \ No newline at end of file diff --git a/test/templates/register.html b/test/templates/register.html deleted file mode 100644 index 94ee63a..0000000 --- a/test/templates/register.html +++ /dev/null @@ -1,19 +0,0 @@ - - -
- {% csrf_token %} -
-

Register

- {% if error_message %}

{{ error_message }}

{% endif %} -
-
-
- -
- -
- - \ No newline at end of file diff --git a/test/templates/test.html b/test/templates/test.html deleted file mode 100644 index d343734..0000000 --- a/test/templates/test.html +++ /dev/null @@ -1,7 +0,0 @@ - - - {% for user in users %} - {{ user }} - {% endfor %} - - \ No newline at end of file diff --git a/test/tests.py b/test/tests.py deleted file mode 100644 index 7ce503c..0000000 --- a/test/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/test/urls.py b/test/urls.py deleted file mode 100644 index 8f117f3..0000000 --- a/test/urls.py +++ /dev/null @@ -1,15 +0,0 @@ -from django.urls import path -from . import views - -urlpatterns = [ - path('', views.home, name='home'), - path('', views.details, name='details'), - path('register_form', views.register_form, name='register_form'), - path('register', views.register, name='register'), - path('login_form', views.login_form, name='login_form'), - path('login', views.login, name='login'), - path('courses', views.courses, name='courses'), - path('change_profil', views.change_profil, name='change_profil'), - path('profil', views.profil, name='profil'), - path('cached', views.cached, name='cached'), -] \ No newline at end of file diff --git a/test/views.py b/test/views.py deleted file mode 100644 index ca3c847..0000000 --- a/test/views.py +++ /dev/null @@ -1,103 +0,0 @@ -from django.shortcuts import render, get_object_or_404 -from django.contrib.auth import get_user_model, authenticate, login, logout -from django.contrib.auth.decorators import login_required -from django.contrib import messages -from django.views.decorators.cache import cache_page - -from .models import Course, Person - -personLoggedIn = "" - -def home(request, person=''): - return render(request, 'home.html', {'person': person}) - -def details(request, course_id): - course = get_object_or_404(Course, pk=course_id) - return render(request, 'details.html', {'course': course}) - -# Handle error messages. -def register(request): - global personLoggedIn - if request.method == 'POST': - person_name = request.POST.get('name') - person_role = request.POST.get('role') - try: - person = Person.objects.get(name=person_name, role=person_role) - return render(request, 'register.html', {'person': Person(name="", role=""), "error_message": "This user already exists!"}) - except Person.DoesNotExist: - person = Person(name=person_name, role=person_role) - person.save() - personLoggedIn = person - return home(request, personLoggedIn) - - return render(request, 'register.html', {'person': Person(name="", role=""), "error_message": "The form has been wrongly filled!"}) - -def login(request): - global personLoggedIn - if request.method == 'POST': - person_name = request.POST.get('name') - person_role = request.POST.get('role') - - try: - person = Person.objects.get(name=person_name, role=person_role) - personLoggedIn = person - return home(request, personLoggedIn) - except: - return render(request, 'login.html', {'person': Person(name="", role=""), "error_message": "No user found!"}) - - return login_form(request) - -def register_form(request): - return render(request, 'register.html', {'person': Person(name="", role="")}) - -def login_form(request): - return render(request, 'login.html', {'person': Person(name="", role="")}) - -def logout(request): - global personLoggedIn - personLoggedIn = "" - return render(request, 'login_form.html', {'person': Person(name="", role="")}) - -def courses(request): - global personLoggedIn - if personLoggedIn == "": - return render(request, 'login.html', {'person': Person(name="", role=""), "error_message": "You must login!"}) - if personLoggedIn.role == "Student": - courses = Course.objects.filter(students=personLoggedIn) - else: - courses = Course.objects.filter(teacher=personLoggedIn) - if type(courses) == Course: - courses = [courses] - return render(request, 'courses.html', {'person': personLoggedIn, 'courses': courses}) - -def change_profil(request): - global personLoggedIn - if personLoggedIn == '': - return render(request, 'login.html', {'person': Person(name="", role=""), "error_message": "You must login!"}) - - if request.method == 'POST': - person_name = request.POST.get('name') - person_role = request.POST.get('role') - - personLoggedIn.name = person_name - personLoggedIn.role = person_role - personLoggedIn.save() - return render(request, 'profil.html', {'person': personLoggedIn}) - - return login_form(request) - -def profil(request): - global personLoggedIn - if personLoggedIn == '': - return render(request, 'login.html', {'person': Person(name="", role=""), "error_message": "You must login!"}) - return render(request, 'profil.html', {'person': personLoggedIn}) - - - - - -@cache_page(60*15) -def cached(request): - user_model = get_user_model() - all_users = user_model.objects.all() - return render(request, 'test.html', {"users": all_users}) \ No newline at end of file