6
\$\begingroup\$

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

\$\endgroup\$
1
  • 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
    Jul 14, 2014 at 12:59

1 Answer 1

2
\$\begingroup\$

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)
\$\endgroup\$
2
  • \$\begingroup\$ Will this work with Django models? \$\endgroup\$
    – broinjc
    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\$ Nov 6, 2014 at 4:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.