django问卷html,Django:动态问卷系统的Model设计

问卷设计的问题

之前的一个网站项目中,对方希望我们实现一个允许用户自定义的问卷系统。我之前也没有什么经验,经过摸索做出了如下的设计,这里和大家分享一下。按照要求,问卷中包含四种不同的问题:单选题

多选题

问答题

图片题

问卷中问题的种类和数量不限。

设计思路

问卷系统首先可以拆解成为两个部分,一是问卷结构的设计,二是答卷结构的设计。二者十分类似,但是又略有不同。

问卷结构设计

一副问卷应当有一个统一的入口,一个对应于『问卷』这一实体概念的抽象。问卷拥有一些描述整体的属性,如创建时间,创建问卷的等等(有的人可能会试图将回答了问卷的用户和这里的问卷本身联系起来,但事实上和这些用户关联的应当是答案)。同时,不同的问题隶属于一个共同的问卷实体。这些问题,既共享一些通用的性质,但是基于不同的具体问题类型而又有不同的特点(选择题和问答题就有不同的属性)。特别的,对于选择题而言,题目和选项又建立起了一对多的关系。综合上面的描述,问卷部分的结构应当如下图所示:

AAffA0nNPuCLAAAAAElFTkSuQmCC

Struction of questionnaire

答卷结构设计

显然,问卷和答卷直接是应该是一对多的。而答卷又是由针对问卷中各个问题的答案组成的。特别的,选择题的答案又指向所选的选项。故而,答卷部分的结构和问卷部分基本是相同的。

示例代码

以开头我说的问题为例。

问卷

首先我们需要为问卷建立一个modelclass Questionnaire(models.Model):

created_at = models.DateTimeField(auto_now_add=True, editable=False)

modified_at = models.DateTimeField(auto_now=True, editable=False)

is_active = models.BooleanField(default=True)

participants = models.ManyToManyField(settings.AUTH_USER_MODEL)

user = models.ForeignKey(settings.AUTH_USER_MODEL)    def __str__(self):

return smart_str(self.user.username + "的问卷")    class Meta:

ordering = ["-created_at"]

由于不同的问题具有一些共享的属性,我们可以创建一个抽象的基类类表示这些共通的属性,例子如下:class Question(models.Model):

"""这个类是单个问题的抽象"""

question = models.CharField(max_length=200, verbose_name="问题")

required = models.BooleanField(default=True, help_text="这个问题是否必须回答")

questionnaire = models.ForeignKey(Questionnaire)

order_in_list = models.IntegerField(default=1)  # 在问卷列表中的顺序,从1开始

created_at = models.DateTimeField(auto_now_add=True, editable=False)

class Meta:

abstract = True

为不同问题类型我们需要创建对应的model:class ChoiceQuestion(Question):

"""选择题"""

multi_choice = models.BooleanField(default=False, verbose_name="是否为多选")

TEXT_QUESTION_TYPE = 0FILE_QUESTION_TYPE = 1class NonChoiceQuestion(Question):

"""主观题"""

type = models.SmallIntegerField(verbose_name="主观题类型",

choices=(

(TEXT_QUESTION_TYPE, '问答题'),

(FILE_QUESTION_TYPE, '文件题')

), default=0)

虽然问题描述中给出了4中不同的问题,但是实际上只需要两类就足以描述。中单选题和多选题只是能够同时选择的选项数量不同,题目本身的描述特点是相同的。而文件题和问答题只是答案的形式不一样,题目本身的描述特点是一样的。(综上来看,问题主要是表现问题的『描述』性)

最后,我们需要为问答题设计选项:class Choice(models.Model):

question = models.ForeignKey(ChoiceQuestion, related_name="choices")

description = models.CharField(max_length=50)

multi_choice = models.BooleanField(default=False, verbose_name="是否为多选")

order_in_list = models.IntegerField(default=1)  # 在选项列表中的顺序,从1开始

答案部分

首先是答卷:class AnswerSheet(models.Model):

"""答卷的抽象"""

user = models.ForeignKey(settings.AUTH_USER_MODEL)      # 答题者

questionnaire = models.ForeignKey(Questionnaire)     # 对应问卷

created_at = models.DateTimeField(auto_now_add=True, editable=False)

modified_at = models.DateTimeField(auto_now=True, editable=False)

is_active = models.BooleanField(default=True)

答案则无法像问题只需要两个类既可以表示,这里我们需要为四种问题设计四种答案类:class Answer(models.Model):

"""答案的基类"""

answer_sheet = models.ForeignKey(AnswerSheet)    class Meta:

abstract = Trueclass SingleChoiceAnswer(Answer):

"""单选题的答案"""

choice = models.ForeignKey(Choice, related_name="single_choice_answers")  # 单选题

question = models.ForeignKey(ChoiceQuestion, related_name="single_choice_answer_set")class MultiChoiceAnswer(Answer):

"""多选题的答案"""

choices = models.ManyToManyField(Choice, related_name="multi_choice_answers")

question = models.ForeignKey(ChoiceQuestion, related_name="multi_choice_answers")class TextAnswer(Answer):

"""文字题的答案"""

text = models.TextField()

question = models.ForeignKey(NonChoiceQuestion)class FileAnswer(Answer):

file = models.ImageField(upload_to="your_upload_path")

question = models.ForeignKey(NonChoiceQuestion)

is_image = models.BooleanField(default=True)

综上我们就完成了这个可定制答卷的model部分。

作者:治部少辅

链接:https://www.jianshu.com/p/a558d5b52348

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本项目是一个简单的django问卷调查系统,拥有完善的权限机制,以及答卷功能,可扩展性强,用户相关登录、退出、改密等功能均在users应用中,course应用为问卷应用,采用vue+django+sqlite3开发,但后期可配置连接到MySQL数据库! 非常适合大学生作为毕业项目进行改造! 上线部署请自行参考django官方文档!如有部署需求可单独咨询报价! 调试步骤: 1、创建虚拟环境,这里只以python默认创建虚拟环境的方式说明 python3 -m venv venv 2、激活虚拟环境 win: venv\Script\activate linux: source venv/bin/activate 3、安装依赖 pip3 install -r requirements.txt 4、启动调试服务器 python3 manage.py runserver 前台所有页面默认均需要登录后方可访问 学生登录后直接进入选择问卷页面,选择问卷确认后直接进入问卷答题页面,成功跳转到个人中心,失败会有失败提示,问卷所有选项在没提交问卷之前均可修改,提交后选项不能修改,一个问卷一个学生只能作答一次,不能重复作答! 老师登录后跳转到个人中心,可修改密码,查看问卷结果,通过问卷结果的学生名可访问该问卷该学生的作答详细信息! 前台登录功能,学生、老师、超管均可登录,登录成功根据角色类型显示不同页面对应不同操作。 超管前台登录权限和老师基本一致,只是查看问卷结果为全员的问卷结果,而老师只能查看自己名下关联课程的问卷! 超管后台登录拥有所有权限,可在后台导出问卷结果及课程详情结果,格式为csv! 超管拥有批量导入用户信息权限! 超管可在后台修改任何用户的密码! 学生及教师均可在前台修改密码、姓名和用户名, 姓名和用户名修改时默认显示在修改框! 超管后台功能列表 用户管理 - 学生、教师信息增删改查! 开课时间 - 【增删改查】添加课程之前必须设置,因为在添加课程是需要选择开课时间,依赖该项! 课程管理 - 【增删改查】添加课程,课程需关联老师及开课时间,请提前创建! 问题管理 - 【增删改查】问题维度已经内置直接选择,问题、权重可修改,问题选项在对应的问题下添加,请注意选择选项多对应的选项号! 问卷管理 - 【增删改查】问卷可多选题库,关联教师,关联课程,请提前创建! 问卷结果 - 【管理员可删除】 可批量导出,可按课程及教师筛选查看! 课程结果 - 课程列表依赖添加的课程,已经有学生答题的课程,在删除课程前需谨慎,会导致之前的结果无法查看! 超管导入用户数据地址:http://127.0.0.1:8000/course/loaddata/user/ 用户数据录入说明: 老师和学生录入信息字段基本一致,id[值唯一]、username[值唯一]、password、code[值唯一,并且不能以0开头]为必填。 user_type字段为用户类型,需要在导入前指明用户类型。【学生类型:XS】【教师类型: TC】【超管类型:CG】。 dept字段为学院类型,因为系统已经固定了几个学院选项,所以不能随意填写,需要与选项中的对应。 # 选项类型 DEPT = ( ('计算机科学学院', '计算机科学学院'), ('文学院', '文学学院'), ('外国语学院', '外国语学院'), ('数学学院', '数学学院'), ) code字段为老师或学生的学号,必须唯一,也是必填项,不能以0开始,不能以0开始,不能以0开始,否则编辑信息不可用excel,只能用txt文本管理器打开编辑! 项目根目录有个01.csv的文件为导入用户信息模板,里边录入的几个用户不能删除,除id之外,其余均可修改, id可以从2开始,1的id是超级管理员的id,可以剔除在外!【目前超管的信息已经在文件中,如果系统创建了超管之后再去导入,文件中的超管id=1的信息会被覆盖】 【文件编码格式必须为: 【CSV UTF-8(逗号分割) 】的.csv文件】 前台登录地址:http://127.0.0.1:8000/users/login/ 后台登录地址:http://127.0.0.1:8000/admin/ 学生测试账户: 账号:studentA 密码:123456 教师测试账户: 账号:teachA 密码:123456 超级管理员: 账号:admin 密码:admin123zxc
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值