Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions onlinecourse/admin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.contrib import admin
# <HINT> Import any new Models here
from .models import Course, Lesson, Instructor, Learner
from .models import Course, Lesson, Instructor, Learner, Question, Choice

# <HINT> Register QuestionInline and ChoiceInline classes here

Expand All @@ -9,14 +9,23 @@ class LessonInline(admin.StackedInline):
model = Lesson
extra = 5

class QuestionInline(admin.StackedInline):
model = Question
extra = 5

class ChoiceInline(admin.StackedInline):
model = Choice
extra = 5

# Register your models here.
class CourseAdmin(admin.ModelAdmin):
inlines = [LessonInline]
inlines = [LessonInline, QuestionInline]
list_display = ('name', 'pub_date')
list_filter = ['pub_date']
search_fields = ['name', 'description']

class QuestionAdmin(admin.ModelAdmin):
inlines = [ChoiceInline]

class LessonAdmin(admin.ModelAdmin):
list_display = ['title']
Expand All @@ -28,3 +37,5 @@ class LessonAdmin(admin.ModelAdmin):
admin.site.register(Lesson, LessonAdmin)
admin.site.register(Instructor)
admin.site.register(Learner)
admin.site.register(Question, QuestionAdmin)
admin.site.register(Choice)
76 changes: 76 additions & 0 deletions onlinecourse/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
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),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
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'),
),
]
Empty file.
46 changes: 43 additions & 3 deletions onlinecourse/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,49 @@ class Enrollment(models.Model):
rating = models.FloatField(default=5.0)


# <HINT> Create a Question Model with:
# Used to persist question content for a course
# Has a One-To-Many (or Many-To-Many if you want to reuse questions) relationship with course
# Has a grade point for each question
# Has question content
# Other fields and methods you would like to design

class Question(models.Model): #class Question(models.Model):
course = models.ForeignKey(Course, on_delete=models.CASCADE) # Foreign key to lesson
question_text = models.TextField() # question text
question_grade = models.FloatField() # question grade/mark

# <HINT> A sample model method to calculate if learner get the score of the question
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

def __str__(self):
return self.question_text


# <HINT> Create a Choice Model with:
# Used to persist choice content for a question
# One-To-Many (or Many-To-Many if you want to reuse choices) relationship with Question
# Choice content
# Indicate if this choice of the question is a correct one or not
# Other fields and methods you would like to design
class Choice(models.Model): # class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_content = models.TextField()
is_correct = models.BooleanField()

def __str__(self):
return self.choice_content

# <HINT> The submission model
# 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 Submission(models.Model):
enrollment = models.ForeignKey(Enrollment, on_delete=models.CASCADE)
choices = models.ManyToManyField(Choice)
149 changes: 110 additions & 39 deletions onlinecourse/templates/onlinecourse/course_detail_bootstrap.html
Original file line number Diff line number Diff line change
@@ -1,56 +1,127 @@
<!DOCTYPE html>
<html lang="en">
<head>
{% load static %}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<head>
{% load static %}
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<meta charset="UTF-8">
</head>
<meta charset="UTF-8" />
</head>

<body>
<body>
<!-- Navigation bar -->
<nav class="navbar navbar-light bg-light">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="{% url 'onlinecourse:index' %}">Home</a>
</div>
<ul class="nav navbar-nav navbar-right">
{% if user.is_authenticated %}
<li>
<a class="btn btn-link" href="#">{{ user.first_name }}({{ user.username }})</a>
<a class="btn btn-link" href="{% url 'onlinecourse:logout' %}">Logout</a>
</li>
{% else %}
<li>
<form class="form-inline" action="{% url 'onlinecourse:login' %}" method="post">
{% csrf_token %}
<div class="input-group">
<input type="text" class="form-control" placeholder="Username" name="username" >
<input type="password" class="form-control" placeholder="Username" name="psw" >
<button class="btn btn-primary" type="submit">Login</button>
<a class="btn btn-link" href="{% url 'onlinecourse:registration' %}">Sign Up</a>
</div>
</form>
</li>
{% endif %}
</ul>
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="{% url 'onlinecourse:index' %}">Home</a>
</div>
<ul class="nav navbar-nav navbar-right">
{% if user.is_authenticated %}
<li>
<a class="btn btn-link" href="#"
>{{ user.first_name }}({{ user.username }})</a
>
<a class="btn btn-link" href="{% url 'onlinecourse:logout' %}"
>Logout</a
>
</li>
{% else %}
<li>
<form
class="form-inline"
action="{% url 'onlinecourse:login' %}"
method="post"
>
{% csrf_token %}
<div class="input-group">
<input
type="text"
class="form-control"
placeholder="Username"
name="username"
/>
<input
type="password"
class="form-control"
placeholder="Username"
name="psw"
/>
<button class="btn btn-primary" type="submit">Login</button>
<a
class="btn btn-link"
href="{% url 'onlinecourse:registration' %}"
>Sign Up</a
>
</div>
</form>
</li>
{% endif %}
</ul>
</div>
</nav>

<!-- Page content -->
<div class="container-fluid">
<h2>{{ course.name }}</h2>
<div class="card-columns-vertical">
{% for lesson in course.lesson_set.all %}
<div class="card mt-1">
<div class="card-header"><h5>Lesson {{lesson.order|add:1}}: {{lesson.title}}</h5></div>
<div class="card-body">{{lesson.content}}</div>
</div>
<h2>{{ course.name }}</h2>
<div class="card-columns-vertical">
{% for lesson in course.lesson_set.all %}
<div class="card mt-1">
<div class="card-header">
<h5>Lesson {{lesson.order|add:1}}: {{lesson.title}}</h5>
</div>
<div class="card-body">{{lesson.content}}</div>
</div>
{% endfor %}
</div>
<button
class="btn btn-block btn-primary"
data-toggle="collapse"
data-target="#demo"
>
Start Exam
</button>

<div id="demo" class="collapse">
<form
id="questionform"
action="{% url 'onlinecourse:exam_submission' course.id %}"
method="post"
>
{% csrf_token %} {% for question in course.question_set.all %}
<div class="card-columns-vertical">
<div class="card mt-1">
<div class="card-header">
<h5>{{ question.question_text}}</h5>
</div>
<div class="form-group">
{% for choice in question.choice_set.all %}
<div class="form-check">
<label class="form-check-label">
<input
type="checkbox"
name="choice_{{choice.id}}"
class="form-check-input"
id="{{choice.id}}"
value="{{choice.id}}"
/>{{ choice.choice_content }}
</label>
</div>
{% endfor %}
</div>
</div>
<!-- Course detail template changes go here -->
</div>
{% endfor %}
<input
class="btn btn-success btn-block"
type="submit"
value="Submit"
/>
</form>
</div>
</div>
</body>
</body>
</html>
Loading