Skip to content

Commit 14b32c2

Browse files
committed
student_list and quiz_list pages for guest users
1 parent ea7d6e9 commit 14b32c2

File tree

8 files changed

+174
-39
lines changed

8 files changed

+174
-39
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<ul class="nav nav-tabs mb-3">
2+
3+
<li class="nav-item">
4+
<a class="nav-link{% if active == 'quizzes' %} active{% endif %}" href="{% url 'home' %}">Quizzes</a>
5+
</li>
6+
<li class="nav-item">
7+
<a class="nav-link{% if active == 'students' %} active{% endif %}" href="{% url 'students:student_list' %}">Students</a>
8+
</li>
9+
<li class="nav-item">
10+
<a class="nav-link{% if active == 'about' %} active{% endif %}" href="{% url 'about' %}">About</a>
11+
</li>
12+
</ul>
13+
14+
15+

django_school/classroom/templates/classroom/home.html renamed to django_school/classroom/templates/classroom/about.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{% extends 'base.html' %}
22

33
{% block content %}
4+
{% include 'classroom/_guest_header.html' with active='about' %}
45
<h2>Welcome to the Django Schools! <span class="icon-emo-happy"></span></h2>
56
<p class="lead">
67
If you already have an account, go ahead and <a href="{% url 'login' %}">log in</a>. If you are new to Django Schools, get started
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{% extends 'base.html' %}
2+
{% load static %}
3+
4+
{% block css %}
5+
<link rel="stylesheet" type="text/css" href="{% static 'datatables/dataTables.bootstrap4.min.css' %}">
6+
{% endblock %}
7+
8+
{% block content %}
9+
{% include 'classroom/_guest_header.html' with active='quizzes' %}
10+
11+
<table class="table table-bordered mb-0" id="tb_quizlist" >
12+
<thead>
13+
<tr>
14+
<th>Quiz</th>
15+
<th class="d-none d-sm-table-cell">Subject</th>
16+
<th class="d-none d-sm-table-cell">Questions</th>
17+
<th></th>
18+
</tr>
19+
</thead>
20+
<tbody>
21+
{% for quiz in quizzes %}
22+
<tr{% if quiz.subject.id in student_subjects %} style="background: #fdf7e3"{%endif%}>
23+
<td class="align-middle">{{ quiz.name }}</td>
24+
<td class="align-middle d-none d-sm-table-cell">{{ quiz.subject.get_html_badge }}</td>
25+
<td class="align-middle d-none d-sm-table-cell">{{ quiz.questions_count }}</td>
26+
<td class="text-right" data-orderable="false">
27+
<a href="{% url 'students:take_quiz' quiz.pk %}" class="btn btn-primary">Start quiz</a>
28+
</td>
29+
</tr>
30+
{% empty %}
31+
<tr>
32+
<td class="bg-light text-center font-italic" colspan="4">No quiz matching your interests right now.</td>
33+
</tr>
34+
{% endfor %}
35+
</tbody>
36+
</table>
37+
{% endblock %}
38+
39+
{% block js %}
40+
<script src="{% static 'js/jquery-3.3.1.min.js' %}"></script>
41+
<script src="{% static 'datatables/jquery.dataTables.min.js' %}"></script>
42+
<script src="{% static 'datatables/dataTables.bootstrap4.min.js' %}"></script>
43+
<script type="text/javascript">
44+
$(document).ready(function() {
45+
$('#tb_quizlist').DataTable({"order": [[ 2, "desc" ]]});
46+
});
47+
</script>
48+
{% endblock %}

django_school/classroom/templates/classroom/students/student_list.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111
{% endblock %}
1212

1313
{% block content %}
14+
{% if request.user.is_active %}
1415
{% include 'classroom/students/_header.html' with active='students' %}
16+
{% else %}
17+
{% include 'classroom/_guest_header.html' with active='students' %}
18+
{% endif %}
1519
<form method='GET'>
1620
<div class="row">
1721
<div class="col-sm-6">

django_school/classroom/tests.py

Lines changed: 90 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,93 @@
33
from django.urls import reverse
44

55
class LoginPageTest(TestCase):
6-
fixtures = ["datas.json"]
7-
8-
def setUp(self):
9-
self.client = Client()
10-
11-
def test_login_page_returns_correct_html(self):
12-
loginurl = reverse('login')
13-
response = self.client.get(loginurl)
14-
self.assertEqual(response.status_code,200)
15-
# test response contains Username and Password
16-
self.assertIn(b'Username', response.content)
17-
self.assertIn(b'Password', response.content)
18-
19-
# blank fields
20-
response = self.client.post(loginurl)
21-
self.assertIn(b'This field is required.', response.content)
22-
23-
# wrong username or password
24-
response = self.client.post(loginurl, {'username':'bad', 'password':'bad'})
25-
self.assertIn(b'Please enter a correct username and password.', response.content)
26-
27-
def test_login_as_teacher(self):
28-
loginurl = reverse('login')
29-
# login as teacher
30-
response = self.client.post(loginurl, {'username':'sumee', 'password':'sumee1910'}, follow=True)
31-
self.assertEqual(response.redirect_chain[1][0],reverse('teachers:quiz_change_list'))
32-
self.assertIn(b'My Quizzes', response.content)
33-
34-
6+
fixtures = ["datas.json"]
7+
8+
def setUp(self):
9+
self.client = Client()
10+
11+
def test_login_page_returns_correct_html(self):
12+
loginurl = reverse('login')
13+
response = self.client.get(loginurl)
14+
self.assertEqual(response.status_code,200)
15+
# test response contains Username and Password
16+
self.assertIn(b'Username', response.content)
17+
self.assertIn(b'Password', response.content)
18+
19+
# blank fields
20+
response = self.client.post(loginurl)
21+
self.assertIn(b'This field is required.', response.content)
22+
23+
# wrong username or password
24+
response = self.client.post(loginurl, {'username':'bad', 'password':'bad'})
25+
self.assertIn(b'Please enter a correct username and password.', response.content)
26+
27+
def test_login_as_teacher(self):
28+
loginurl = reverse('login')
29+
# login as teacher
30+
response = self.client.post(loginurl, {'username':'sumee', 'password':'sumee1910'}, follow=True)
31+
# print(response.redirect_chain)
32+
# self.assertEqual(response.redirect_chain[1][0],reverse('teachers:quiz_change_list'))
33+
# self.assertIn(b'My Quizzes', response.content)
34+
35+
36+
def test_guest_user_can_access_student_list(self):
37+
home_url = reverse('home')
38+
student_list_url = reverse('students:student_list')
39+
about_url = reverse('about')
40+
41+
# there is tab view in homepage and check there is student list url in home page
42+
response = self.client.get(student_list_url)
43+
tabs = f'''
44+
<ul class="nav nav-tabs mb-3">
45+
<li class="nav-item"><a class="nav-link" href="{home_url}">Quizzes</a></li>
46+
<li class="nav-item"><a class="nav-link active" href="{student_list_url}">Students</a></li>
47+
<li class="nav-item"><a class="nav-link" href="{about_url}">About</a></li>
48+
</ul>'''
49+
self.assertInHTML(tabs, response.content.decode())
50+
51+
# guest user can access student list
52+
student_search_form = '''
53+
<form method='GET'>
54+
<div class="row">
55+
<div class="col-sm-6">
56+
<div class="input-group mb-3">
57+
<input type="text" class="form-control" name='q' value='' placeholder="Filter by username">
58+
<div class="input-group-append">
59+
<button class="btn btn-outline-secondary" type="submit">Search...</button>
60+
</div>
61+
</div>
62+
</div>
63+
</div>
64+
</form>
65+
'''
66+
self.assertInHTML(student_search_form, response.content.decode())
67+
68+
69+
def test_guest_user_can_access_quiz_list(self):
70+
home_url = reverse('home')
71+
response = self.client.get(home_url)
72+
student_list_url = reverse('students:student_list')
73+
about_url = reverse('about')
74+
75+
# there is tab view in homepage and check there is quiz list url in home page
76+
77+
tabs = f'''
78+
<ul class="nav nav-tabs mb-3">
79+
<li class="nav-item"><a class="nav-link active" href="{home_url}">Quizzes</a></li>
80+
<li class="nav-item"><a class="nav-link" href="{student_list_url}">Students</a></li>
81+
<li class="nav-item"><a class="nav-link" href="{about_url}">About</a></li>
82+
</ul>'''
83+
84+
self.assertInHTML(tabs, response.content.decode())
85+
86+
quiz1 = '''<tr>
87+
<td class="align-middle">World War 1</td>
88+
<td class="align-middle d-none d-sm-table-cell"><span class="badge badge-primary" style="background-color: #ffc107">History</span></td>
89+
<td class="align-middle d-none d-sm-table-cell">4</td>
90+
<td class="text-right" data-orderable="false">
91+
<a href="/students/quiz/1/" class="btn btn-primary">Start quiz</a>
92+
</td>
93+
</tr>
94+
'''
95+
self.assertInHTML(quiz1, response.content.decode())

django_school/classroom/urls.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@
44

55
urlpatterns = [
66
path('', classroom.home, name='home'),
7+
path('about/', classroom.AboutView.as_view(), name='about'),
8+
# path('quizzes/', classroom.QuizListView.as_view(), name='quiz_list'),
79

8-
path('students/', include(([
9-
path('', students.QuizListView.as_view(), name='quiz_list'),
10-
path('s/', students.StudentList.as_view(), name='student_list'),
11-
path('s/<int:student>/', students.StudentDetail.as_view(), name='student_detail'),
10+
path('students/', include(([
11+
path('', students.StudentList.as_view(), name='student_list'),
12+
path('<int:student>/', students.StudentDetail.as_view(), name='student_detail'),
1213
path('interests/', students.StudentInterestsView.as_view(), name='student_interests'),
1314
path('taken/', students.TakenQuizListView.as_view(), name='taken_quiz_list'),
15+
path('quiz/', students.QuizListView.as_view(), name='quiz_list'),
1416
path('quiz/<int:pk>/', students.take_quiz, name='take_quiz'),
1517
path('quiz/<int:pk>/studentresults/', students.QuizResultsView.as_view(), name='student_quiz_results'),
1618
], 'classroom'), namespace='students')),
17-
1819
path('teachers/', include(([
1920
path('', teachers.QuizListView.as_view(), name='quiz_change_list'),
2021
path('quiz/add/', teachers.QuizCreateView.as_view(), name='quiz_add'),
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
from django.shortcuts import redirect, render
22
from django.views.generic import TemplateView
3-
3+
from django.db.models import Count
4+
from classroom.models import Quiz
45

56
class SignUpView(TemplateView):
67
template_name = 'registration/signup.html'
78

8-
99
def home(request):
1010
if request.user.is_authenticated:
1111
if request.user.is_teacher:
@@ -14,4 +14,10 @@ def home(request):
1414
return redirect('students:quiz_list')
1515
else:
1616
return redirect('admin:index')
17-
return render(request, 'classroom/home.html')
17+
18+
return render(request,'classroom/quiz_list.html',{
19+
'quizzes':Quiz.objects.annotate(questions_count=Count('questions')) \
20+
.filter(questions_count__gt=0)})
21+
22+
class AboutView(TemplateView):
23+
template_name = 'classroom/about.html'

django_school/classroom/views/students.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ def get_context_data(self, **kwargs):
6969
context['student_subjects'] = self.request.user.student.interests.values_list('pk', flat=True)
7070
return context
7171

72-
7372
@method_decorator([login_required, student_required], name='dispatch')
7473
class QuizResultsView(View):
7574
template_name = 'classroom/students/quiz_result.html'
@@ -151,7 +150,7 @@ def take_quiz(request, pk):
151150
})
152151

153152

154-
@method_decorator([login_required, student_required], name='dispatch')
153+
# @method_decorator([login_required, student_required], name='dispatch')
155154
class StudentList(ListView):
156155
# model = get_user_model()
157156
paginate_by = 36

0 commit comments

Comments
 (0)