我正在为Django中的测验系统创建一个模型。每个问题都有问题和5个选项。
class Question(models.Model):
quiz_question=models.CharField(max_length=1000)
option1=models.CharField(max_length=500)
option2=models.CharField(max_length=500)
option3=models.CharField(max_length=500)
option4=models.CharField(max_length=500)
option5=models.CharField(max_length=500)
这里只有一个答案是正确答案。这是代表答案的最佳方式吗?是通过添加另一个字段还是可以通过编辑现有字段来完成?
答案 0 :(得分:1)
几个月前,我有类似于基于问题系统的django项目。
在您的情况下,我认为您需要为Answer
模型创建ForeignKey
的新Question
模型。
这是我的models.py
:
from django.db import models
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.db.models import (Q, Count, Sum)
from django.utils.translation import ugettext, ugettext_lazy as _
from django.utils.encoding import python_2_unicode_compatible
class TimeStampedModel(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class QuestionQuerySet(models.QuerySet):
def published(self):
return self.filter(publish=True)
@python_2_unicode_compatible
class Question(TimeStampedModel):
title = models.CharField(max_length=200)
TYPE_CHOICES = (
('short', _('Sort')),
('medium', _('Medium')),
('complete', _('Complete'))
)
type = models.CharField(
max_length=200,
choices=TYPE_CHOICES,
default='short'
)
weight = models.PositiveIntegerField()
publish = models.BooleanField(default=True)
objects = QuestionQuerySet.as_manager()
def __str__(self):
return self.title
@property
def total_score(self):
answer = Answer.objects.filter(
question__pk=self.pk
).annotate(Sum('score'))
return answer # .count()
def get_answers(self):
return Answer.objects.filter(
question__pk=self.pk
)
get_answers.allow_tags = True
class Meta:
verbose_name = _('Detail Question')
verbose_name_plural = _('Questions')
ordering = ['-created']
@python_2_unicode_compatible
class Answer(models.Model):
question = models.ForeignKey(
Question, related_name='question_answer'
)
answer = models.CharField(max_length=200)
score = models.PositiveIntegerField()
def key_generator():
import uuid
key = uuid.uuid4().hex
if BaseAnswerUser.objects.filter(key=key).exists():
return "{0}-{1}".format(key, uuid.uuid4().hex)
return key
@python_2_unicode_compatible
class BaseAnswerUser(TimeStampedModel):
"""
To save the answers that already answered by user.
in this case, is such as session method.
"""
user = models.ForeignKey(
User, related_name='user_answer'
)
key = models.CharField(
max_length=200,
unique=True,
default=key_generator
)
def get_absolute_url(self):
return reverse('result', kwargs={'key': self.key})
def get_answers(self):
return AnswerUser.objects.filter(
base_answer__key=self.key
)
def __str__(self):
return _('Result analyze for %(user)s') % {
'user': self.user.username,
}
class Meta:
verbose_name = _('Base Answer User')
verbose_name_plural = _('Base Answer Users')
ordering = ['-created']
@python_2_unicode_compatible
class AnswerUser(TimeStampedModel):
question = models.ForeignKey(
Question, related_name='question_answer_user'
)
base_answer = models.ForeignKey(
BaseAnswerUser, related_name='base_answer_user'
)
score = models.PositiveIntegerField(
null=True, blank=True
)
text_answer = models.TextField(
null=True, blank=True
)
@property
def weight(self):
return self.question.weight
def __str__(self):
return _('Result for %(question)s') % {
'question': self.question
}
class Meta:
verbose_name = _('Detail User Answer')
verbose_name_plural = _('User Answers')
ordering = ['-created']
为了处理仪表板django admin中的答案,我使用了admin.TabularInline
。有关详情,您可以通过此gist
希望它有用......
我之前的回答是动态答案系统,例如:
问题A (有4个选项答案)
问题B (有3个选项答案)
如果您实施 静态答案 系统,据我所知:
会话答疑用户 在我之前的回答中表示为 基本答案用户 ;
[ Question ] -------------------+
- title (chr) |
- description (chr) |
- weight (int) |
| |
| |
| |
\./ \./
[ Answer ] [ Answer User ]
- fk_question (int) - fk_question (int)
- option_a (chr) - fk_session_answer (int)
- scroe_a (int) - score (int) # save the final score
- option_b (chr) /'\
- score_b (int) |
|
|
|
[ Session Answer User ]
- fk_user (int)
- session_key (char:unique)
- created (date)
|
|
\./
[ User Model ]
- username (chr)
- date_joined (date)
一个例子我想找到特定用户和特定会话的总分。
>>>
>>> session = get_object_or_404(SessionAnswerUser, user=request.user, session_key='key-key-key')
>>> answered_questions = AnswerUser.objects.filter(session_answer=session)
>>>
>>> # Find total scores. eg: {'score__sum': 15}
>>> answered_questions.aggregate(Sum('score'))['score__sum']
15
>>>
session_key
?用户回答完所有问题(创建模式)后,再重定向到结果页面。一个例子:
@login_required
def save_answers(request):
"""
This view isn't using django forms,
but only handling at the templates and this view.
Because until now I don't know how to handle it.
"""
if request.method == 'POST':
# retrieve all id/pk's from the `questions` (model:Question)
questions = request.POST.getlist('question')
# retrieve all id/pk's from the `answers`. (model:Answer)
answers = [request.POST['answer-{}'.format(q)] for q in questions]
# saving the session with `key_generator()`, see my previous answer.
session = SessionAnswerUser.objects.create(user=request.user)
session.save()
# Makesure the length of `questions` is same with length of `answers`
# 1 answer for 1 question
if len(questions) == len(answers):
for n in range(len(questions)):
dict_answer = {
'question': Question.objects.get(pk=questions[n]),
'session': session, # from latest session above
'score': answers[n]
}
answered_questions = AnswerUser.objects.create(**dict_answer)
answered_questions.save()
# redirecting to the result page.
return redirect('/result/page', key=session.session_key)
else:
# length of `questions` is not same with length of `answers`
# do stuff...
@login_required
def result_page(request, key):
session = get_object_or_404(SessionAnswerUser, session_key=key)
answered_questions = AnswerUser.objects.filter(session=session)
# I hope you already know how to use the django queryset.
# eg:
# >>> session.user
# <User: john smith>
# >>>
# >>> answered_questions
# <QuerySet: [<AnswerUser: foobar lorem>, <AnswerUser: xxxx>]>
# >>>
# >>> answered_questions.first()
# <AnswerUser: foobar lorem>
# >>> answered_questions.first().score
# 3
...
# your context goes here..