Django:動態問卷系統的Model設計
問卷設計的問題
之前的一個網站專案中,對方希望我們實現一個允許使用者自定義的問卷系統。我之前也沒有什麼經驗,經過摸索做出瞭如下的設計,這裡和大家分享一下。按照要求,問卷中包含四種不同的問題:
單選題
多選題
問答題
圖片題
問卷中問題的種類和數量不限。
設計思路
問卷系統首先可以拆解成為兩個部分,一是問卷結構的設計,二是答卷結構的設計。二者十分類似,但是又略有不同。
問卷結構設計
一副問卷應當有一個統一的入口,一個對應於『問卷』這一實體概念的抽象。問卷擁有一些描述整體的屬性,如建立時間,建立問卷的等等(有的人可能會試圖將回答了問卷的使用者和這裡的問卷本身聯絡起來,但事實上和這些使用者關聯的應當是答案)。同時,不同的問題隸屬於一個共同的問卷實體。這些問題,既共享一些通用的性質,但是基於不同的具體問題型別而又有不同的特點(選擇題和問答題就有不同的屬性)。特別的,對於選擇題而言,題目和選項又建立起了一對多的關係。綜合上面的描述,問卷部分的結構應當如下圖所示:
Struction of questionnaire
答卷結構設計
顯然,問卷和答卷直接是應該是一對多的。而答卷又是由針對問卷中各個問題的答案組成的。特別的,選擇題的答案又指向所選的選項。故而,答卷部分的結構和問卷部分基本是相同的。
示例程式碼
以開頭我說的問題為例。
問卷
首先我們需要為問卷建立一個model
class 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部分。
作者:治部少輔
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4692/viewspace-2810050/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- (一)django-game:model 設計DjangoGAM
- 許可權系統設計(5)--動態性
- 【分散式系統設計簡卷(0)】MapReduce分散式
- Django的User ModelDjango
- 自由經濟系統的設計(二):生態設計
- django動態urlDjango
- Django的User Model(2)Django
- 設計資產管理系統的疑問
- Django模型modelDjango模型
- 請教個動態報表設計的問題
- Django 公共模型欄位的設定和繼承(AuditBaseModel、ApprovalBaseModel)Django模型繼承APP
- 雪亮工程動態視訊監控系統建設動態人臉識別系統搭建
- MongoDB實現問卷/考試設計MongoDB
- 調查問卷資料庫設計資料庫
- Django的路由系統Django路由
- Django之ModelFormDjangoORM
- Django ModelFrom元件Django元件
- [譯] 構建未來的設計生態系統
- 【Django】Django快取系統Django快取
- Java動態程式設計---動態代理Java程式設計
- rabbitMq實現系統內的簡訊傳送設計&動態獲取BEANMQBean
- 系統設計架構:有狀態與無狀態架構
- 動作遊戲系統設計概述遊戲
- PHP自定義問卷調查的設計及思路PHP
- win10系統設定桌面動態桌布的方法Win10
- 關於這樣的系統設計,求問?
- 06 Django-動態urlDjango
- Django model總結(上)Django
- 6.djnago實現問卷調查系統Go
- linux下實現問卷調查系統Linux
- 作業系統:計算機的生態系統作業系統計算機
- 系統設計思想之Domain驅動AI
- 請教高手一個系統設計的問題
- 後設資料管理—動態表單設計器在crudapi系統中完整實現API
- 設計模式:動態代理設計模式
- 系統重啟後卷不能自動掛載
- 深入理解Django的ModelForm操作DjangoORM
- vue 動態繫結 v-modelVue