【问题标题】:Django quiz application, REST, how to design models?Django测验应用程序,REST,如何设计模型?
【发布时间】:2014-03-23 01:51:12
【问题描述】:

我正在构建 django 测验应用程序,所有数据(问题/答案)都应该可以通过 REST 服务获得。 我会为此使用美味的馅饼。

我想到了完美的结果 JSON,它可能看起来像(带答案的单个问题):

{
    "level": 1,
    "question": "Example question",
    "choices":[
        {
            "content":"Example answer 1",
            "valid": true
        },
        {
            "content":"Example answer 2",
            "valid": false
        },
        {
            "content":"Example answer 3",
            "valid": false
        },
        {
            "content":"Example answer 4",
            "valid": false
        }
    ]
},

单个问题总是包含 4 个答案,其中一个或多个有效。

我不确定我应该如何为这种模式设计 django 模型。

我应该使用问题外键创建“答案”模型吗?在这种情况下,其他解决方案可能会更好吗? 如果是这样,我如何使用 django admin/web 表单轻松添加新问题?

有什么想法或建议吗?

【问题讨论】:

  • 您是否允许他们选择多个有效的答案。您在每个问题中提到了多个有效答案。
  • 没错,每个问题(如上)将包含 4 个答案,其中一个或多个有效。什么不清楚?

标签: django django-models django-forms tastypie


【解决方案1】:

我过去使用过的一个模型结构如下:

class Questionnaire(models.Model):
    version = models.CharField()

class Question(models.Model):
    questionnaire = models.ForeignKey(Questionnaire)
    text = models.CharField()

class QuestionAnswer(models.Model):
    question = models.ForeignKey(Question)
    text = models.CharField()
    is_valid = models.BooleanField()

class UserAnswer(models.Model):
    answer = models.ForeignKey(QuestionAnswer)

此解决方案可让您设计多个问卷/测验,每个问卷的问题数量不定。然后每个问题会有不同数量的答案,您可以选择有效的答案。

这种设计的最大问题是它实际上不利于部分问卷/测验的完成。如果这是一个破坏者,您可以按如下方式调整 UserAnswer 类:

class UserQuestionnaire(models.Model):
    questionnaire = models.ForeignKey(Questionnaire)
    completed = models.BooleanField()

class UserAnswer(models.Model):
    answer = models.ForeignKey(QuestionAnswer)
    user_questionnaire = models.ForeignKey(UserQuestionnaire)

这会稍微破坏规范化,但可以让您设置一个标志来判断接受者是否完成。

希望这可以帮助您入门!

【讨论】:

    【解决方案2】:

    我在 Medium 上写了这个非常好的教程。 https://medium.com/@nsjcorps/create-a-quiz-application-with-django-rest-framework-react-redux-part-one-f0fcae5103fd 但通常应该是这样的。

    我也在 YouTube 上制作了这个播放列表:https://www.youtube.com/watch?v=I4LEMajjdjA&list=PLOOcfkIFw3os58bzJjtUfcmRae_Ht_dFw

    from django.db import models
    from django.contrib.auth.models import User
    from django.template.defaultfilters import slugify
    from django.db.models.signals import post_save, pre_save
    from django.dispatch import receiver
    
    class Quiz(models.Model):
       name = models.CharField(max_length=1000)
       questions_count = models.IntegerField(default=0)
       description = models.CharField(max_length=70)
       created = models.DateTimeField(auto_now_add=True,null=True,blank=True)
       slug = models.SlugField()
       roll_out = models.BooleanField(default=False)
    
       class Meta:
           ordering = [‘created’,]
           verbose_name_plural =”Quizzes”
    
       def __str__(self):
           return self.name
    
    
    class Question(models.Model):
       quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
       label = models.CharField(max_length=1000)
       order = models.IntegerField(default=0)
    
       def __str__(self):
          return self.label
    
    class Answer(models.Model):
       question = models.ForeignKey(Question, on_delete=models.CASCADE)
       text = models.CharField(max_length=1000)
       is_correct = models.BooleanField(default=False)
    
       def __str__(self):
           return self.text
    
    
    class QuizTakers(models.Model):
       user = models.ForeignKey(User, on_delete=models.CASCADE)
       quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
       correct_answers = models.IntegerField(default=0)
       completed = models.BooleanField(default=False)
       timestamp = models.DateTimeField(auto_now_add=True)
    
       def __str__(self):
          return self.user.username
    
    
    class Response(models.Model):
        quiztaker = models.ForeignKey(QuizTakers, on_delete=models.CASCADE)
        question = models.ForeignKey(Question, on_delete=models.CASCADE)
        answer = models.ForeignKey(Answer,on_delete=models.CASCADE,null=True,blank=True)
        def __str__(self):
            return self.question.label
    
    
    @receiver(post_save, sender=Quiz)
    def set_default_quiz(sender, instance, created,**kwargs):
       quiz = Quiz.objects.filter(id = instance.id)
    
    
    
     quiz.update(questions_count=instance.question_set.filter(quiz=instance.pk).count())
    @receiver(post_save, sender=Question)
    def set_default(sender, instance, created,**kwargs):
     quiz = Quiz.objects.filter(id = instance.quiz.id)
     quiz.update(questions_count=instance.quiz.question_set.filter(quiz=instance.quiz.pk).count())
    @receiver(pre_save, sender=Quiz)
    def slugify_title(sender, instance, *args, **kwargs):
     instance.slug = slugify(instance.name)```
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-03
      • 1970-01-01
      • 2016-06-07
      • 1970-01-01
      • 2018-11-14
      • 2019-11-16
      • 1970-01-01
      相关资源
      最近更新 更多