I'm working on a little django quiz taking app. Currently I'm making it's models. So far I've got Quiz
, Question
, Answer
, and Response
designed as follows:
from django.db import models
from npage.mixins import TranslatedModelMixin
from django.contrib.auth.models import User
# Create your models here.
class Quiz(models.Model):
title = models.CharField(max_length=60,blank=False,)
# show_feedback = models.BooleanField(blank=False,default=True,help_text="Correct answer is shown after question.",)
class Meta:
verbose_name = "Quiz"
verbose_name_plural = "Quizzes"
def __unicode__(self):
return self.title
class Question(models.Model, TranslatedModelMixin):
quiz = models.ManyToManyField(Quiz, blank=True, )
content = models.CharField(max_length=1000, blank=False, help_text="Enter the question text that you want displayed",verbose_name='Question',)
es_content = models.CharField(max_length=1000, blank=True, help_text="Enter the question text that you want displayed",verbose_name='Question',)
type = models.CharField(max_length=8, choices=TYPES, default='radio')
is_scoreable = models.BooleanField(default=True, help_text="Will the answer to this question be scored?")
# idea
# tags = models.CharField(max_length=1000, blank=False, help_text="Enter some text to help you find this question to add it to quizzes later on.",verbose_name='Question',)
feedback = models.TextField(max_length=2000,blank=True,help_text="Explanation to be shown after the question has been answered.",verbose_name='Explanation',)
es_feedback = models.TextField(max_length=2000,blank=True,help_text="Explanation to be shown after the question has been answered.",verbose_name='Explanation',)
TYPES = (
('radio', 'radio'),
('checkbox', 'checkbox'),
('text', 'text'),
)
language_code = 'en'
translated_fields = ['content', 'feedback']
class Meta:
verbose_name = "Question"
verbose_name_plural = "Questions"
#ordering = ['category']
def __unicode__(self):
return self.content
class Answer(models.Model, TranslatedModelMixin):
question = models.ForeignKey(Question)
content = models.CharField(max_length=1000, blank=False, help_text="Enter the answer text that you want displayed",)
es_content = models.CharField(max_length=1000, blank=False, help_text="Enter the answer text that you want displayed",)
correct = models.BooleanField(blank=False, default=False,help_text="Is this a correct answer?")
language_code = 'en'
translated_fields = ['content']
def __unicode__(self):
return self.content
class Response(models.Model):
user = models.ForeignKey(User)
question = models.ForeignKey(Question)
# Could have either an FK to an answer OR some free response text.
answer = models.ForeignKey(Answer)
free_response = models.TextField(max_length=2000,blank=True)
def __unicode__(self):
if self.answer:
return self.answer
else:
return free_response
I am especially concerned with the elegance of my Response
model. The idea here is a question might be multiple choice (radio group or checkbox group) OR free response (text) so a response
could either be a foreign key to an answer
(which may or may not be correct) OR just some plain text (probably not both). Is this a good design? What can I do to improve my models
-
1\$\begingroup\$ Thank you for using my quiz app, I hope that it is helpful. I have added few changes which you might find useful: github.com/tomwalker/django_quiz \$\endgroup\$user49205– user492052014年07月14日 12:59:32 +00:00Commented Jul 14, 2014 at 12:59
1 Answer 1
You could have an abstract superclass Response
which has concrete derived classes of multipleChoiceResponse
and freeResponse
. Then you can have a method such as checkResponse
which is different for each type of respones.
EDIT:
How about this:
from django.db import models
class Response(models.Model):
user = models.ForeignKey(User)
question = models.ForeignKey(Question)
class Meta:
abstract = True
class freeResponse(Response):
free_response = models.TextField(max_length=2000,blank=True)
class multipleChoiceResponse(Response) #does not handle multi-select (tickbox) cases
answer = models.ForeignKey(Answer)
-
\$\begingroup\$ Will this work with Django models? \$\endgroup\$broinjc– broinjc2014年11月06日 04:12:40 +00:00Commented Nov 6, 2014 at 4:12
-
\$\begingroup\$ You can do inheritance with Django models. The example above does not handle the multi-select (tickbox) case, but it handles the radio-button case. You could add a method called checkResponse() which could do the checking for you. Also there might be a boolean in the superclass
correct = True
? \$\endgroup\$M. K. Hunter– M. K. Hunter2014年11月06日 04:24:26 +00:00Commented Nov 6, 2014 at 4:24