首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >问答系统模型场选择

问答系统模型场选择
EN

Stack Overflow用户
提问于 2017-01-29 08:53:04
回答 1查看 504关注 0票数 1

我正在为Django.There中的问答系统创建一个模型,每个问题有5个选项。

代码语言:javascript
复制
    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)

这里只有一个答案是正确的answer.Which是最好的方式来表示这里的答案?它是通过添加另一个字段来实现的,还是可以通过编辑一个现有字段来完成呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-29 09:53:14

几个月前,我有一个类似的基于问题系统的django项目。在您的例子中,我认为您需要创建一个新的Answer模型,将ForeignKey转换为Question模型。

这是我的models.py

代码语言:javascript
复制
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']

为了处理dashboard django管理中的答案,我使用了admin.TabularInline。有关更多信息,您可以在此要旨结帐。

并了解如何处理Django名称相同的多个输入字段值

希望能帮上忙..。

更新

我以前的答案是动态答案系统,举个例子:

  1. 问题A(有4个选项答案)
代码语言:javascript
复制
- a). Option answer A
- b). Option answer B
- c). Option answer C
- d). Option answer D

  1. 问题B(有三个选项答案)
代码语言:javascript
复制
- a). Option answer A
- b). Option answer B
- c). Option answer C

如果您实现了静态应答系统,据我所知:

会话应答用户表示为来自我以前的答案的基本应答用户

代码语言:javascript
复制
[ 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)

问集怎么样?

例如,我希望找到特定用户和特定会话的总分。

代码语言:javascript
复制
>>>
>>> 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

在用户回答了所有问题(创建模式)后,然后重定向到结果页。举个例子:

代码语言:javascript
复制
@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..
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41919152

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档