Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

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

share|improve this question
1  
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 –  user49205 Jul 14 '14 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)
share|improve this answer
    
Will this work with Django models? –  broinjc Nov 6 '14 at 4:12
    
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? –  M. K. Hunter Nov 6 '14 at 4:24

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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