Pamela Fox commited on
Commit
1dbd98a
·
1 Parent(s): 013c0dc

Admin changes

Browse files
quizzes/admin.py CHANGED
@@ -1,7 +1,15 @@
1
  from django.contrib import admin
2
- from .models import Quiz, Question, FreeTextAnswer, MultipleChoiceAnswer
3
 
4
  admin.site.register(Quiz)
5
- admin.site.register(Question)
6
- admin.site.register(FreeTextAnswer)
7
- admin.site.register(MultipleChoiceAnswer)
 
 
 
 
 
 
 
 
 
1
  from django.contrib import admin
2
+ from .models import Quiz, Question, Answer, FreeTextAnswer, MultipleChoiceAnswer
3
 
4
  admin.site.register(Quiz)
5
+
6
+ class FreeTextAnswerInline(admin.StackedInline):
7
+ model = FreeTextAnswer
8
+
9
+ class MultipleChoiceAnswerInline(admin.StackedInline):
10
+ model = MultipleChoiceAnswer
11
+
12
+ class QuestionAdmin(admin.ModelAdmin):
13
+ inlines = [FreeTextAnswerInline, MultipleChoiceAnswerInline]
14
+
15
+ admin.site.register(Question, QuestionAdmin)
quizzes/migrations/0002_remove_question_answer_status_and_more.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Generated by Django 4.1.1 on 2022-09-15 00:57
2
+
3
+ from django.db import migrations, models
4
+ import django.db.models.deletion
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+
9
+ dependencies = [
10
+ ("quizzes", "0001_initial"),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.RemoveField(
15
+ model_name="question",
16
+ name="answer_status",
17
+ ),
18
+ migrations.AlterField(
19
+ model_name="freetextanswer",
20
+ name="question",
21
+ field=models.OneToOneField(
22
+ on_delete=django.db.models.deletion.CASCADE, to="quizzes.question"
23
+ ),
24
+ ),
25
+ migrations.AlterField(
26
+ model_name="multiplechoiceanswer",
27
+ name="question",
28
+ field=models.OneToOneField(
29
+ on_delete=django.db.models.deletion.CASCADE, to="quizzes.question"
30
+ ),
31
+ ),
32
+ ]
quizzes/models.py CHANGED
@@ -28,10 +28,9 @@ class Quiz(models.Model):
28
  class Question(models.Model):
29
  quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
30
  prompt = models.CharField(max_length=200)
31
- answer_status = models.CharField(default='unanswered', max_length=16)
32
 
33
  def __str__(self):
34
- return f"<Question: {self.prompt}>"
35
 
36
  def display(self):
37
  print(self.prompt)
@@ -44,15 +43,22 @@ class Question(models.Model):
44
  print(f"Sorry, it was: {self.answer.correct_answer}")
45
  self.answer_status = 'incorrect'
46
 
47
-
48
- # Create your models here.
49
- class FreeTextAnswer(models.Model):
50
- question = models.ForeignKey(Question, on_delete=models.CASCADE)
 
51
  correct_answer = models.CharField(max_length=200)
 
 
 
 
 
 
52
  case_sensitive = models.BooleanField(default=False)
53
 
54
  def __str__(self):
55
- return f"<FreeTextAnswer: {self.correct_answer}>"
56
 
57
  def is_correct(self, user_answer):
58
  if not self.case_sensitive:
@@ -65,13 +71,11 @@ class FreeTextAnswer(models.Model):
65
  else:
66
  print("Type your answer in (don't worry about capitalization):")
67
 
68
- class MultipleChoiceAnswer(models.Model):
69
- question = models.ForeignKey(Question, on_delete=models.CASCADE)
70
- correct_answer = models.CharField(max_length=200)
71
  choices = fields.ArrayField(models.CharField(max_length=200, blank=True))
72
 
73
  def __str__(self):
74
- return f"<MultipleChoiceAnswer: {self.correct_answer} of {self.choices}>"
75
 
76
  def is_correct(self, user_answer):
77
  """Assumes user answer is number corresponding to answer."""
 
28
  class Question(models.Model):
29
  quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
30
  prompt = models.CharField(max_length=200)
 
31
 
32
  def __str__(self):
33
+ return self.prompt
34
 
35
  def display(self):
36
  print(self.prompt)
 
43
  print(f"Sorry, it was: {self.answer.correct_answer}")
44
  self.answer_status = 'incorrect'
45
 
46
+ class Answer(models.Model):
47
+ question = models.OneToOneField(
48
+ Question,
49
+ on_delete=models.CASCADE
50
+ )
51
  correct_answer = models.CharField(max_length=200)
52
+
53
+
54
+ class Meta:
55
+ abstract = True
56
+
57
+ class FreeTextAnswer(Answer):
58
  case_sensitive = models.BooleanField(default=False)
59
 
60
  def __str__(self):
61
+ return self.correct_answer
62
 
63
  def is_correct(self, user_answer):
64
  if not self.case_sensitive:
 
71
  else:
72
  print("Type your answer in (don't worry about capitalization):")
73
 
74
+ class MultipleChoiceAnswer(Answer):
 
 
75
  choices = fields.ArrayField(models.CharField(max_length=200, blank=True))
76
 
77
  def __str__(self):
78
+ return f"{self.correct_answer} from {self.choices}"
79
 
80
  def is_correct(self, user_answer):
81
  """Assumes user answer is number corresponding to answer."""
quizzes/templates/quizzes/display.html ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE HTML>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width">
6
+ <title>Quiz {{ quiz.id }}</title>
7
+ </head>
8
+ <body>
9
+ <h1>{{ quiz.name }}</h1>
10
+
11
+ <form action="{% url 'quizzes:grade' question.id %}" method="post">
12
+ {% csrf_token %}
13
+ {% for question in quiz.question_set.all %}
14
+ <section>
15
+ <h3>{{ question.prompt }}</h3>
16
+ {% if question.freetextanswer %}
17
+ <input type="text" name="{{ question.pk }}">
18
+ {% else %}
19
+ {% for choice in question.multiplechoiceanswer.choices %}
20
+ <label>
21
+ <input type="radio" name="{{ question.pk }}" value="{{ choice }}">
22
+ {{ choice}}
23
+ </label>
24
+ {% endfor %}
25
+ {% endif %}
26
+ </section>
27
+ {% endfor %}
28
+
29
+ <button type="submit">Check answers</button>
30
+ </form>
31
+ </body>
32
+ </html>
quizzes/templates/quizzes/index.html ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE HTML>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width">
6
+ <title>Quizzes</title>
7
+ </head>
8
+ <body>
9
+ {% if quiz_list %}
10
+ <ul>
11
+ {% for quiz in quiz_list %}
12
+ <li><a href="{% url 'quizzes:display' quiz.id %}">{{ quiz.name }}</a></li>
13
+ {% endfor %}
14
+ </ul>
15
+ {% else %}
16
+ <p>No quizzes are available.</p>
17
+ {% endif %}
18
+ </body>
19
+ </html>
quizzes/urls.py CHANGED
@@ -2,9 +2,11 @@ from django.urls import path
2
 
3
  from . import views
4
 
 
 
5
  urlpatterns = [
6
  path('', views.index, name='index'),
7
- # ex: /polls/5/
8
  path('<int:quiz_id>/', views.display, name='display'),
 
9
 
10
  ]
 
2
 
3
  from . import views
4
 
5
+ app_name = 'quizzes'
6
+
7
  urlpatterns = [
8
  path('', views.index, name='index'),
 
9
  path('<int:quiz_id>/', views.display, name='display'),
10
+ path('<int:quiz_id>/grade/', views.grade, name='grade'),
11
 
12
  ]
quizzes/views.py CHANGED
@@ -1,7 +1,18 @@
1
- from django.http import HttpResponse
 
 
2
 
3
  def index(request):
4
- return HttpResponse("Here are all the quizzes")
 
 
 
5
 
6
  def display(request, quiz_id):
7
- return HttpResponse("You're looking at quiz %s." % quiz_id)
 
 
 
 
 
 
 
1
+ from django.shortcuts import get_object_or_404,render
2
+
3
+ from .models import Quiz
4
 
5
  def index(request):
6
+ quiz_list = Quiz.objects.all()
7
+ context = {'quiz_list': quiz_list}
8
+ return render(request, 'quizzes/index.html', context)
9
+
10
 
11
  def display(request, quiz_id):
12
+ quiz = get_object_or_404(Quiz, pk=quiz_id)
13
+ return render(request, 'quizzes/display.html', {'quiz': quiz})
14
+
15
+
16
+ def grade(request, quiz_id):
17
+ quiz = get_object_or_404(Quiz, pk=quiz_id)
18
+ return render(request, 'quizzes/display.html', {'quiz': quiz})