Python django多项选择题测验应用程序模型

Python django多项选择题测验应用程序模型,python,django,postgresql,Python,Django,Postgresql,我正在django中创建测验应用程序,我的django问题模型是这样的 class Question(models.Model): questions = models.CharField(max_length=50, unique=True) choice1 = models.CharField(max_length=50, unique=True) choice2 = models.CharField(max_length=50, unique=True) c

我正在django中创建测验应用程序,我的django问题模型是这样的

class Question(models.Model):
    questions = models.CharField(max_length=50, unique=True)
    choice1 = models.CharField(max_length=50, unique=True)
    choice2 = models.CharField(max_length=50, unique=True)
    choice3 = models.CharField(max_length=50, unique=True)
    choice4 = models.CharField(max_length=50, unique=True)
    correct_answer = models.CharField(max_length=50, unique=True)

这很好,或者将四个选项保存在postgres数组中,或者将选项保存在单独的表中。

对于正确规范化的关系数据库架构,您需要一个独特的
选项
模型,并在
问题
上使用外键:

class Question(models.Model):
    question = models.CharField(...)

class Choice(models.Model):
    question = models.ForeignKey("Question", related_name="choices")
    choice = modelsCharField("Choice", max_length=50)
    position = models.IntegerField("position")

    class Meta:
        unique_together = [
            # no duplicated choice per question
            ("question", "choice"), 
            # no duplicated position per question 
            ("question", "position") 
        ]
        ordering = ("position",)
然后,您可以使用
myquestion.choices.all()
(并使用
mychoice.Question
选项中获取问题)

请注意,这不会对一个问题的选择数量施加任何限制,甚至不会要求一个问题至少有一个相关的选择


除非您有非常令人信服的理由不这样做,否则在使用关系数据库时,您需要的是一个正确的规范化模式(rdbms不仅仅是比特桶,它们提供了大量有用的特性,只要您有一个正确的模式即可)

本教程介绍了所有内容

不过,以下是总结:

来自django.db导入模型的

从django.contrib.auth.models导入用户
从django.template.defaultfilters导入slugify
从django.db.models.signals导入后保存、前保存
从django.dispatch导入接收方
课堂测验(models.Model):
name=models.CharField(最大长度=1000)
问题计数=models.IntegerField(默认值=0)
description=models.CharField(最大长度=70)
created=models.DateTimeField(auto\u now\u add=True,null=True,blank=True)
slug=models.SlugField()
roll_out=models.BooleanField(默认值=False)
类元:
排序=[‘已创建’,]
详细名称复数=“测验”
定义(自我):
返回self.name
课堂提问(models.Model):
测验=模型.ForeignKey(测验,on_delete=模型.CASCADE)
label=models.CharField(最大长度=1000)
order=models.IntegerField(默认值=0)
定义(自我):
返回自我标签
课堂答案(models.Model):
问题=models.ForeignKey(问题,on_delete=models.CASCADE)
text=models.CharField(最大长度=1000)
is_correct=models.BooleanField(默认值=False)
定义(自我):
返回self.text
课堂提问者(models.Model):
user=models.ForeignKey(用户,on_delete=models.CASCADE)
测验=模型.ForeignKey(测验,on_delete=模型.CASCADE)
正确答案=models.IntegerField(默认值=0)
已完成=models.BooleanField(默认值=False)
timestamp=models.DateTimeField(auto\u now\u add=True)
定义(自我):
返回self.user.username
类响应(models.Model):
quiztaker=models.ForeignKey(quiztaker,on_delete=models.CASCADE)
问题=models.ForeignKey(问题,on_delete=models.CASCADE)
answer=models.ForeignKey(answer,on_delete=models.CASCADE,null=True,blank=True)
定义(自我):
返回self.question.label
@接收者(保存后,发送者=测验)
def set_default_测验(发送方、实例、已创建、**kwargs):
quick=quick.objects.filter(id=instance.id)
update(questions\u count=instance.question\u set.filter(quick=instance.pk.count())
@接收方(保存后,发送方=问题)
def set_默认值(发送方、实例、已创建、**kwargs):
quick=quick.objects.filter(id=instance.quick.id)
update(questions\u count=instance.quick.question\u set.filter(quick=instance.quick.pk.count())
@接收者(预保存,发送者=测验)
def slugify_标题(发送方、实例、*args、**kwargs):
instance.slug=slugify(instance.name)

如果您使用的是postgres sql,则可以使用arryfield

类QuizMcqDetail(基本模型):
title=models.CharField(最大长度=255,null=True,blank=True)
time_limit=models.TimeField()
开始日期=models.DateTimeField(null=True,blank=True)
end_date=models.DateTimeField(null=True,blank=True)
可用语言=models.ManyToManyField(QuizLanguage,related\u name='available\u language',blank=True)
问题\u计数=模型。正整数字段(默认值=10)
is_active=models.BooleanField(默认值=True)
定义(自我):
返回自己的标题
课堂提问(基本模型):
s_no=models.PositiveIntegerField()
quick=models.ForeignKey(QuizMcqDetail,on_delete=models.CASCADE,related_name='quick\u mcq')
问题文本=models.TextField(最大长度=200)
选项=阵列字段(models.CharField(最大长度=200))
应答位置=数组字段(models.IntegerField())
解释=models.TextField(null=True)
language=models.ForeignKey(QuizLanguage,related\u name='question\u language',on\u delete=models.SET\u NULL,NULL=True)
定义(自我):
返回self.question\u文本
类QuizMcqSelect(基本模型):
quick\u question=models.ForeignKey(QuizMcqQuestion,related\u name=“select\u quick\u mcq”,on\u delete=models.CASCADE)
user=models.ForeignKey(user,related\u name=“user\u select\u quick\u mcq”,on\u delete=models.CASCADE)
答案=models.BooleanField(默认值=False)
选定的\u答案=数组字段(models.IntegerField())
定义(自我):
返回f“{self.quick_question}{self.user}{self.answer}”
def保存(自身、*args、**kwargs):
如果self.quick\u question.answer\u position==self.selected\u答案:
self.answer=True
其他:
self.answer=False
super().save(*args,**kwargs)

如何在单个字段(如postgres数组)中保存多项选择,我还需要保存正确的答案。您要求推荐设计模型的最佳方法。我的建议是使用正确规范化的模式。如果您想使用一些非规范化的模式,请这样做,但我不会回答这个问题,因为我认为这不会真的有帮助。如果你想知道为什么,试一下这两种解决方案,看看哪一种能让你在处理答案、分数和任何关于你的问题/选择/答案的统计数据时更轻松。谢谢。现在只有我明白你想说的了。