diff --git a/existing_file.html b/existing_file.html new file mode 100644 index 00000000..e69de29b diff --git a/onlinecourse/admin.py b/onlinecourse/admin.py index ffd8a631..d7da2ed1 100644 --- a/onlinecourse/admin.py +++ b/onlinecourse/admin.py @@ -1,30 +1,32 @@ from django.contrib import admin # Import any new Models here -from .models import Course, Lesson, Instructor, Learner - +from .models import Course, Lesson, Instructor, Learner, Question, Choice, Submission # Register QuestionInline and ChoiceInline classes here - - class LessonInline(admin.StackedInline): model = Lesson extra = 5 - - +class ChoiceInline(admin.StackedInline): + model = Choice + extra = 2 +class QuestionInline(admin.StackedInline): + model = Question + extra = 2 # Register your models here. class CourseAdmin(admin.ModelAdmin): inlines = [LessonInline] list_display = ('name', 'pub_date') list_filter = ['pub_date'] search_fields = ['name', 'description'] - - +class QuestionAdmin(admin.ModelAdmin): + inlines = [ChoiceInline] + list_display = ['content'] class LessonAdmin(admin.ModelAdmin): list_display = ['title'] - - # Register Question and Choice models here - admin.site.register(Course, CourseAdmin) admin.site.register(Lesson, LessonAdmin) admin.site.register(Instructor) admin.site.register(Learner) +admin.site.register(Question, QuestionAdmin) +admin.site.register(Choice) +admin.site.register(Submission) \ No newline at end of file diff --git a/onlinecourse/migrations/0001_initial.py b/onlinecourse/migrations/0001_initial.py new file mode 100644 index 00000000..ddf93461 --- /dev/null +++ b/onlinecourse/migrations/0001_initial.py @@ -0,0 +1,78 @@ +# Generated by Django 4.2.3 on 2024-08-07 17:40 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Course', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(default='online course', max_length=30)), + ('image', models.ImageField(upload_to='course_images/')), + ('description', models.CharField(max_length=1000)), + ('pub_date', models.DateField(null=True)), + ('total_enrollment', models.IntegerField(default=0)), + ], + ), + migrations.CreateModel( + name='Lesson', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(default='title', max_length=200)), + ('order', models.IntegerField(default=0)), + ('content', models.TextField()), + ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='onlinecourse.course')), + ], + ), + migrations.CreateModel( + name='Learner', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('occupation', models.CharField(choices=[('student', 'Student'), ('developer', 'Developer'), ('data_scientist', 'Data Scientist'), ('dba', 'Database Admin')], default='student', max_length=20)), + ('social_link', models.URLField()), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Instructor', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('full_time', models.BooleanField(default=True)), + ('total_learners', models.IntegerField()), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='Enrollment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date_enrolled', models.DateField(default=django.utils.timezone.now)), + ('mode', models.CharField(choices=[('audit', 'Audit'), ('honor', 'Honor'), ('BETA', 'BETA')], default='audit', max_length=5)), + ('rating', models.FloatField(default=5.0)), + ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='onlinecourse.course')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.AddField( + model_name='course', + name='instructors', + field=models.ManyToManyField(to='onlinecourse.instructor'), + ), + migrations.AddField( + model_name='course', + name='users', + field=models.ManyToManyField(through='onlinecourse.Enrollment', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/onlinecourse/migrations/0002_choice_submission_question_choice_question.py b/onlinecourse/migrations/0002_choice_submission_question_choice_question.py new file mode 100644 index 00000000..d4df4373 --- /dev/null +++ b/onlinecourse/migrations/0002_choice_submission_question_choice_question.py @@ -0,0 +1,44 @@ +# Generated by Django 4.2.3 on 2024-08-07 17:59 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('onlinecourse', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Choice', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content', models.CharField(max_length=200)), + ('is_correct', models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name='Submission', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('choices', models.ManyToManyField(to='onlinecourse.choice')), + ('enrollment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='onlinecourse.enrollment')), + ], + ), + migrations.CreateModel( + name='Question', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content', models.CharField(max_length=200)), + ('grade', models.IntegerField(default=50)), + ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='onlinecourse.course')), + ], + ), + migrations.AddField( + model_name='choice', + name='question', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='onlinecourse.question'), + ), + ] diff --git a/onlinecourse/models.py b/onlinecourse/models.py index f6fbcbb5..1b6e4365 100644 --- a/onlinecourse/models.py +++ b/onlinecourse/models.py @@ -5,11 +5,8 @@ except Exception: print("There was an error loading django modules. Do you have django installed?") sys.exit() - from django.conf import settings import uuid - - # Instructor model class Instructor(models.Model): user = models.ForeignKey( @@ -18,11 +15,8 @@ class Instructor(models.Model): ) full_time = models.BooleanField(default=True) total_learners = models.IntegerField() - def __str__(self): return self.user.username - - # Learner model class Learner(models.Model): user = models.ForeignKey( @@ -46,12 +40,9 @@ class Learner(models.Model): default=STUDENT ) social_link = models.URLField(max_length=200) - def __str__(self): return self.user.username + "," + \ self.occupation - - # Course model class Course(models.Model): name = models.CharField(null=False, max_length=30, default='online course') @@ -62,20 +53,15 @@ class Course(models.Model): users = models.ManyToManyField(settings.AUTH_USER_MODEL, through='Enrollment') total_enrollment = models.IntegerField(default=0) is_enrolled = False - def __str__(self): return "Name: " + self.name + "," + \ "Description: " + self.description - - # Lesson model class Lesson(models.Model): title = models.CharField(max_length=200, default="title") order = models.IntegerField(default=0) course = models.ForeignKey(Course, on_delete=models.CASCADE) content = models.TextField() - - # Enrollment model # Once a user enrolled a class, an enrollment entry should be created between the user and course # And we could use the enrollment to track information such as exam submissions @@ -93,11 +79,23 @@ class Enrollment(models.Model): date_enrolled = models.DateField(default=now) mode = models.CharField(max_length=5, choices=COURSE_MODES, default=AUDIT) rating = models.FloatField(default=5.0) - - -# One enrollment could have multiple submission -# One submission could have multiple choices -# One choice could belong to multiple submissions -#class Submission(models.Model): -# enrollment = models.ForeignKey(Enrollment, on_delete=models.CASCADE) -# choices = models.ManyToManyField(Choice) +class Question(models.Model): + course = models.ForeignKey(Course, on_delete=models.CASCADE) + content = models.CharField(max_length=200) + grade = models.IntegerField(default=50) + def __str__(self): + return "Question: " + self.content + def is_get_score(self, selected_ids): + all_answers = self.choice_set.filter(is_correct=True).count() + selected_correct = self.choice_set.filter(is_correct=True, id__in=selected_ids).count() + if all_answers == selected_correct: + return True + else: + return False +class Choice(models.Model): + question = models.ForeignKey(Question, on_delete=models.CASCADE) + content = models.CharField(max_length=200) + is_correct = models.BooleanField(default=False) +class Submission(models.Model): + enrollment = models.ForeignKey(Enrollment, on_delete=models.CASCADE) + choices = models.ManyToManyField(Choice) \ No newline at end of file diff --git a/onlinecourse/templates/onlinecourse/course_detail_bootstrap.html b/onlinecourse/templates/onlinecourse/course_detail_bootstrap.html index fb48e939..8d5d297d 100644 --- a/onlinecourse/templates/onlinecourse/course_detail_bootstrap.html +++ b/onlinecourse/templates/onlinecourse/course_detail_bootstrap.html @@ -51,6 +51,33 @@

{{ course.name }}

{% endfor %} + {% if user.is_authenticated %} +
+ +
+
+ {% for question in course.question_set.all %} +
+
+
{{ question.content }}
+
+ {% csrf_token %} +
+ {% for choice in question.choice_set.all %} +
+ +
+ {% endfor %} +
+
+ {% endfor %} + +
+
+{% endif %} diff --git a/onlinecourse/templates/onlinecourse/exam_result_bootstrap.html b/onlinecourse/templates/onlinecourse/exam_result_bootstrap.html index 264728f5..7b598234 100644 --- a/onlinecourse/templates/onlinecourse/exam_result_bootstrap.html +++ b/onlinecourse/templates/onlinecourse/exam_result_bootstrap.html @@ -12,6 +12,7 @@ +