Browse Source

Add progress bar. Fix login error message. Update bs4 files.

master
Vitor Freitas 3 years ago
parent
commit
d93795d549
No known key found for this signature in database GPG Key ID: 11D07CF62D8BE9DE
  1. 2
      django_school/classroom/forms.py
  2. 2
      django_school/classroom/templates/classroom/home.html
  3. 3
      django_school/classroom/templates/classroom/students/take_quiz_form.html
  4. 13
      django_school/classroom/views/students.py
  5. 9
      django_school/static/css/app.css
  6. 142
      django_school/templates/base.html
  7. 31
      django_school/templates/registration/login.html

2
django_school/classroom/forms.py

@ -23,7 +23,7 @@ class StudentSignUpForm(UserCreationForm):
interests = forms.ModelMultipleChoiceField(
queryset=Subject.objects.all(),
widget=forms.CheckboxSelectMultiple,
required=False
required=True
)
class Meta(UserCreationForm.Meta):

2
django_school/classroom/templates/classroom/home.html

@ -14,5 +14,5 @@
based on their interests.
</p>
<p>Want to run this code locally? <a href="">Read detailed instructions on how to run this project</a>.</p>
<p>Vitor Freitas<br><a href="https://twitter.com/vitorfs/">@vitorfs</a></p>
<p class="mb-0">Vitor Freitas<br><a href="https://twitter.com/vitorfs/">@vitorfs</a></p>
{% endblock %}

3
django_school/classroom/templates/classroom/students/take_quiz_form.html

@ -3,6 +3,9 @@
{% load crispy_forms_tags %}
{% block content %}
<div class="progress mb-3">
<div class="progress-bar" role="progressbar" aria-valuenow="{{ progress }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ progress }}%"></div>
</div>
<h2 class="mb-3">{{ quiz.name }}</h2>
<p class="lead">{{ question.text }}</p>
<form method="post" novalidate>

13
django_school/classroom/views/students.py

@ -83,10 +83,11 @@ def take_quiz(request, pk):
if student.quizzes.filter(pk=pk).exists():
return render(request, 'students/taken_quiz.html')
question = student.get_unanswered_questions(quiz).first()
if not question:
TakenQuiz.objects.create(student=student, quiz=quiz, score=0)
return redirect('students:quiz_list')
total_questions = quiz.questions.count()
unanswered_questions = student.get_unanswered_questions(quiz)
total_unanswered_questions = unanswered_questions.count()
progress = 100 - round(((total_unanswered_questions - 1) / total_questions) * 100)
question = unanswered_questions.first()
if request.method == 'POST':
form = TakeQuizForm(question=question, data=request.POST)
@ -98,7 +99,6 @@ def take_quiz(request, pk):
if student.get_unanswered_questions(quiz).exists():
return redirect('students:take_quiz', pk)
else:
total_questions = quiz.questions.count()
correct_answers = student.quiz_answers.filter(answer__question__quiz=quiz, answer__is_correct=True).count()
score = round((correct_answers / total_questions) * 100.0, 2)
TakenQuiz.objects.create(student=student, quiz=quiz, score=score)
@ -113,5 +113,6 @@ def take_quiz(request, pk):
return render(request, 'classroom/students/take_quiz_form.html', {
'quiz': quiz,
'question': question,
'form': form
'form': form,
'progress': progress
})

9
django_school/static/css/app.css

@ -55,4 +55,13 @@ footer a {
color: #fff;
background-color: #66598B;
border-color: #66598B;
}
.has-danger .radio,
.has-danger .checkbox {
color: #dc3545;
}
.has-danger .invalid-feedback {
display: block;
}

142
django_school/templates/base.html

@ -1,80 +1,80 @@
{% load static %}<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>{% block title %}Django School{% endblock %}</title>
<link rel="icon" href="{% static 'img/favicon.png' %}">
<link href="https://fonts.googleapis.com/css?family=Clicker+Script" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css" integrity="sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="{% static 'vendor/fontello-2f186091/css/fontello.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/app.css' %}">
{% if user.is_authenticated and user.is_teacher %}
<link rel="stylesheet" type="text/css" href="{% static 'css/teachers.css' %}">
{% else %}
<link rel="stylesheet" type="text/css" href="{% static 'css/students.css' %}">
{% endif %}
</head>
<body>
<a href="https://github.com/sibtc/django-multiple-user-types-example"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/38ef81f8aca64bb9a64448d0d70f1308ef5341ab/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"></a>
<div class="container my-4">
<div class="row justify-content-center">
<div class="col-md-10 col-sm-12">
<div class="row">
<div class="col-6">
<h1 class="logo">
<a href="{% url 'home' %}">
Django School
{% if user.is_authenticated %}
{% if user.is_teacher %}
<span class="icon-feather" data-toggle="tooltip" data-placement="right" title="Teacher profile"></span>
{% else %}
<span class="icon-graduation-cap" data-toggle="tooltip" data-placement="right" title="Student profile"></span>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>{% block title %}Django School{% endblock %}</title>
<link rel="icon" href="{% static 'img/favicon.png' %}">
<link href="https://fonts.googleapis.com/css?family=Clicker+Script" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="{% static 'vendor/fontello-2f186091/css/fontello.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/app.css' %}">
{% if user.is_authenticated and user.is_teacher %}
<link rel="stylesheet" type="text/css" href="{% static 'css/teachers.css' %}">
{% else %}
<link rel="stylesheet" type="text/css" href="{% static 'css/students.css' %}">
{% endif %}
</head>
<body>
<a href="https://github.com/sibtc/django-multiple-user-types-example"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/38ef81f8aca64bb9a64448d0d70f1308ef5341ab/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"></a>
<div class="container my-4">
<div class="row justify-content-center">
<div class="col-md-10 col-sm-12">
<div class="row">
<div class="col-6">
<h1 class="logo">
<a href="{% url 'home' %}">
Django School
{% if user.is_authenticated %}
{% if user.is_teacher %}
<span class="icon-feather" data-toggle="tooltip" data-placement="right" title="Teacher profile"></span>
{% else %}
<span class="icon-graduation-cap" data-toggle="tooltip" data-placement="right" title="Student profile"></span>
{% endif %}
{% endif %}
{% endif %}
</a>
</h1>
</a>
</h1>
</div>
<div class="col-6 text-right">
{% if user.is_authenticated %}
<p class="pt-3">Logged in as <strong>{{ user.username }}</strong>. <a href="{% url 'logout' %}">Log out</a>.</p>
{% else %}
<a href="{% url 'login' %}" class="btn btn-light" role="button">Log in</a>
<a href="{% url 'signup' %}" class="btn btn-primary" role="button">Sign up</a>
{% endif %}
</div>
</div>
<div class="col-6 text-right">
{% if user.is_authenticated %}
<p class="pt-3">Logged in as <strong>{{ user.username }}</strong>. <a href="{% url 'logout' %}">Log out</a>.</p>
{% else %}
<a href="{% url 'login' %}" class="btn btn-light" role="button">Log in</a>
<a href="{% url 'signup' %}" class="btn btn-primary" role="button">Sign up</a>
{% endif %}
<div class="card mb-3">
<div class="card-body">
{% for message in messages %}
<div class="alert {{ message.tags }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
{% endfor %}
{% block content %}
{% endblock %}
</div>
</div>
<footer>
<a href="https://simpleisbetterthancomplex.com">© SimpleIsBetterThanComplex.com</a>
/
<a href="#">Read more about this example</a>
/
<a href="https://github.com/sibtc/django-multiple-user-types-example">GitHub repository</a>
</footer>
</div>
<div class="card mb-3">
<div class="card-body">
{% for message in messages %}
<div class="alert {{ message.tags }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
{% endfor %}
{% block content %}
{% endblock %}
</div>
</div>
<footer>
<a href="https://simpleisbetterthancomplex.com">© SimpleIsBetterThanComplex.com</a>
/
<a href="#">Read more about this example</a>
/
<a href="https://github.com/sibtc/django-multiple-user-types-example">GitHub repository</a>
</footer>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/js/bootstrap.min.js" integrity="sha384-a5N7Y/aK3qNeh15eJKGWxsqtnX/wWdSZSKp+81YjTmS15nvnvxKHuzaWwXHDli+4" crossorigin="anonymous"></script>
<script type="text/javascript">
$(function () {
$('[data-toggle="tooltip"]').tooltip();
})
</script>
</body>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<script type="text/javascript">
$(function () {
$('[data-toggle="tooltip"]').tooltip();
})
</script>
</body>
</html>

31
django_school/templates/registration/login.html

@ -3,15 +3,26 @@
{% load crispy_forms_tags %}
{% block content %}
<div class="row">
<div class="col-lg-4 col-md-6 col-sm-8 col-12">
<h2>Log in</h2>
<form method="post" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{ next }}">
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Log in</button>
</form>
</div>
{% if form.non_field_errors %}
<div class="alert alert-danger alert-dismissible fade show" role="alert">
{% for error in form.non_field_errors %}
<p{% if forloop.last %} class="mb-0"{% endif %}>{{ error }}</p>
{% endfor %}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
{% endif %}
<div class="row">
<div class="col-lg-4 col-md-6 col-sm-8 col-12">
<h2>Log in</h2>
<form method="post" novalidate>
{% csrf_token %}
<input type="hidden" name="next" value="{{ next }}">
{{ form.username|as_crispy_field }}
{{ form.password|as_crispy_field }}
<button type="submit" class="btn btn-primary">Log in</button>
</form>
</div>
</div>
{% endblock %}
Loading…
Cancel
Save