前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Django实战-调查问卷表设计优化

Django实战-调查问卷表设计优化

作者头像
小团子
发布2019-10-09 15:40:52
1.8K0
发布2019-10-09 15:40:52
举报
文章被收录于专栏:数据云团数据云团

Django网络应用开发的5项基础核心技术包括模型(Model)的设计,URL 的设计与配置,View(视图)的编写,Template(模板)的设计和Form(表单)的使用。

在django中,有一个记录了项目中所有model元数据的表,就是ContentType,表中一条记录对应着一个存在的model,所以可以通过一个ContentType表的id和一个具体表中的id找到任何记录,及先通过ContenType表的id可以得到某个model,再通过model的id得到具体的对象。

在上一个 调查问卷表设计 中,实现了简单的问卷系统并生成问卷记录。一个问卷系统主要包括:问卷,问卷中每个题目,每个题目的答案,以及生成问卷记录。

如果项目有另外一个需求,也需要与SurveryRecord建立外键关系,那么此时应该怎么做呢?是再给上面的表增加一个外键,然后重新修改数据库么?显然是不能,一旦数据库被创建了,几乎很少再去修改数据,如果再给其添加额外字段,无疑会带来不必要的麻烦。为此,可以利用Django自带的ContentType类,来做这件事情。

代码语言:javascript
复制

from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
代码语言:javascript
复制
class Survery(models.Model):
    """
    问卷
    ID        name            by_class      creator
    1    第一次班级调查      大一计算机205班     张老师
    """
    name = models.CharField(verbose_name="调查问卷名称", max_length=128, unique=True)
    by_class = models.ForeignKey("ClassList", verbose_name="问卷调查班级", on_delete=models.SET_NULL, blank=True, null=True)
    date = models.DateTimeField(verbose_name="问卷创建日期", auto_now_add=True)
    creator = models.ForeignKey("UserInfo", verbose_name="创建者", on_delete=models.SET_NULL, blank=True, null=True)
代码语言:javascript
复制
class SurveryItem(models.Model):
    """
    问卷题目
    ID                 survery                       name                   date          answer_type
     1    1(代表上面创建的第一次班级调查)      您最喜欢吃什么水果?         xxx-xxx-xx             1
    """
    survery = models.ForeignKey('Survery', verbose_name='问卷', on_delete=models.SET_NULL, blank=True, null=True)
    name = models.CharField(verbose_name="调查问题", max_length=255)
    date = models.DateField(auto_now_add=True)
    answer_type_choices = (
        (1, "打分(1~10分)"),
        (2, "单选"),
        (3, "建议"),
    )
    answer_type = models.IntegerField(verbose_name="问题类型", choices=answer_type_choices, default=1)
代码语言:javascript
复制
class SurveryChoices(models.Model):
    """
    问卷选项答案(针对选项类型)
    ID    item    content   points
    1       2       A         10分
    1       2       B         9分
    1       2       C         8分
    1       2       D         7分
    """
    item = models.ForeignKey('SurveryItem', verbose_name='问题', on_delete=models.SET_NULL, blank=True, null=True)
    content = models.CharField(verbose_name='内容', max_length=256)
    points = models.IntegerField(verbose_name='分值')
    surveryrecord = GenericRelation("SurveryRecord")

将评分和建议从问卷记录中单独提取作为一个模型类

代码语言:javascript
复制
class Score(models.Model):
    """
    问卷评分
    """
    item = models.ForeignKey('SurveryItem', verbose_name='问题', blank=True, null=True, on_delete=models.SET_NULL)
    points = models.IntegerField(verbose_name='分值')
    surveryrecord = GenericRelation("SurveryRecord")


class Suggestion(models.Model):
    """
    问卷建议
    """
    item = models.ForeignKey('SurveryItem', verbose_name='问题', blank=True, null=True, on_delete=models.SET_NULL)
    suggests = content = models.CharField(verbose_name='内容', max_length=256)
    surveryrecord = GenericRelation("SurveryRecord")

如果一个表与其它表有多个外键关系,可以通过ContentType来解决这种关联

代码语言:javascript
复制
class SurveryRecord(models.Model):
    """
    问卷记录
    ID    survery      student_name   survery_item  content_type  object_id  
    1        1            1               1              1             1
    1        1            1               2              1              2
    1        1            1               3              1               3
    """
    survery = models.ForeignKey("Survery", verbose_name="问卷", blank=True, null=True, on_delete=models.SET_NULL)
    student_name = models.ForeignKey("Student", verbose_name="学员姓名", blank=True, null=True, on_delete=models.SET_NULL)
    survery_item = models.ForeignKey('SurveryItem', verbose_name="调查项", blank=True, null=True, on_delete=models.SET_NULL)

    content_type = models.ForeignKey(ContentType, blank=True, null=True)
    object_id = models.PositiveIntegerField(blank=True, null=True)
    content_object = GenericForeignKey('content_type', 'object_id') # 这个字段不会再数据库中存在,只是在查询时有用

    date = models.DateTimeField(verbose_name="答题日期", auto_now_add=True) 
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据云团 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档