问题 如何在Django中进行可自定义的用户调查


我正在为一家公司制作一个系统,除其他事项外,必须掌握有关各种事物的满意程度的信息,我使用固定问题和答案的固定模型使其工作正常,但我确信他们需要更改或添加问题。

所以我想建立一个系统,用户可以在其中制作由他们定义的自定义问题组成的自定义评估模式。我该如何制作这样的设计?

现在我的模型就是这个,但错了:

RATING_CHOICES = ((0, u"Good"), (1, u"Bad"), (2, u"Dunno"),)

class EvaluationScheme(models.Model):
    title = models.CharField(max_length=200)

class Evaluation(models.Model):
    doctor = models.CharField(max_length=200)
    agency = models.CharField(max_length=200)
    scheme = models.ForeignKey(EvaluationScheme)

class EvaluationQuestion(models.Model):
    question = models.CharField(max_length=200)
    evaluation = models.ForeignKey(EvaluationScheme)

    def __unicode__(self):
        return self.question

class EvaluationAnswer(models.Model):
    evaluation = models.ForeignKey(Evaluation)
    question = models.ForeignKey(EvaluationQuestion)
    answer = models.SmallIntegerField(choices=RATING_CHOICES)

这是我想要的,除了EvaluationScheme是无用的,因为您仍然必须自己选择所有问题和答案 - 它不会显示仅与选择的模式相关的问题的列表。


2936
2018-06-26 10:43


起源



答案:


我觉得你的模特很好。我使用Django管理员创建了一个带有EvaluationQuestions的EvaluationScheme,然后我创建了一个评估,我能够回答它的问题。这是我以前使用你的模型的代码:

# forms.py:
from django.forms.models import inlineformset_factory
import models

AnswerFormSet = inlineformset_factory(models.Evaluation, 
        models.EvaluationAnswer, exclude=('question',), 
        extra=0, can_delete=False)

# views.py
from django.http import HttpResponse
from django.shortcuts import render_to_response, get_object_or_404
import models, forms

def prepare_blank_answers(evaluation):
    for question in evaluation.scheme.evaluationquestion_set.all():
        answer = models.EvaluationAnswer(evaluation=evaluation,
                                         question=question)
        answer.save()

def answer_form(request, id):
    evaluation = get_object_or_404(models.Evaluation, id=id)
    if len(evaluation.evaluationanswer_set.all()) == 0:
        prepare_blank_answers(evaluation)
    if request.method == 'POST':
        formset = forms.AnswerFormSet(request.POST, instance=evaluation)
        if formset.is_valid():
            formset.save()
            return HttpResponse('Thank you!')
    else:
        formset = forms.AnswerFormSet(instance=evaluation)
    return render_to_response('answer_form.html',
            {'formset':formset, 'evaluation':evaluation})


# answer_form.html:
<html><head></head><body>
  Doctor: {{ evaluation.doctor }} <br>
  Agency: {{ evaluation.agency }}
  <form method="POST">
    {{ formset.management_form }}
    <table>
      {% for form in formset.forms %}
        <tr><th colspan="2">{{ form.instance.question }}</th></tr>
        {{ form }}
      {% endfor %}
    </table>
    <input type="submit">
  </form>
</body></html>

5
2018-06-27 13:10



感谢您的贡献 - 但问题是当您添加多个EvaluationScheme时 - 您可以回答所有问题,而不仅仅是与创建的方案相关的问题。至少这是我在使用管理界面时遇到的问题。但也许我需要在这些表格上做一些AJAX。 - John Magistr
如果你在这里使用我的代码,你不应该有这个问题。我的代码中的关键行是“for evaluation.scheme.evaluationquestion_set.all()”中的问题,它只捕获与此评估方案相关的那些问题。如果您的代码没有这样的行,您将遇到报告的问题。 - krubo


答案:


我觉得你的模特很好。我使用Django管理员创建了一个带有EvaluationQuestions的EvaluationScheme,然后我创建了一个评估,我能够回答它的问题。这是我以前使用你的模型的代码:

# forms.py:
from django.forms.models import inlineformset_factory
import models

AnswerFormSet = inlineformset_factory(models.Evaluation, 
        models.EvaluationAnswer, exclude=('question',), 
        extra=0, can_delete=False)

# views.py
from django.http import HttpResponse
from django.shortcuts import render_to_response, get_object_or_404
import models, forms

def prepare_blank_answers(evaluation):
    for question in evaluation.scheme.evaluationquestion_set.all():
        answer = models.EvaluationAnswer(evaluation=evaluation,
                                         question=question)
        answer.save()

def answer_form(request, id):
    evaluation = get_object_or_404(models.Evaluation, id=id)
    if len(evaluation.evaluationanswer_set.all()) == 0:
        prepare_blank_answers(evaluation)
    if request.method == 'POST':
        formset = forms.AnswerFormSet(request.POST, instance=evaluation)
        if formset.is_valid():
            formset.save()
            return HttpResponse('Thank you!')
    else:
        formset = forms.AnswerFormSet(instance=evaluation)
    return render_to_response('answer_form.html',
            {'formset':formset, 'evaluation':evaluation})


# answer_form.html:
<html><head></head><body>
  Doctor: {{ evaluation.doctor }} <br>
  Agency: {{ evaluation.agency }}
  <form method="POST">
    {{ formset.management_form }}
    <table>
      {% for form in formset.forms %}
        <tr><th colspan="2">{{ form.instance.question }}</th></tr>
        {{ form }}
      {% endfor %}
    </table>
    <input type="submit">
  </form>
</body></html>

5
2018-06-27 13:10



感谢您的贡献 - 但问题是当您添加多个EvaluationScheme时 - 您可以回答所有问题,而不仅仅是与创建的方案相关的问题。至少这是我在使用管理界面时遇到的问题。但也许我需要在这些表格上做一些AJAX。 - John Magistr
如果你在这里使用我的代码,你不应该有这个问题。我的代码中的关键行是“for evaluation.scheme.evaluationquestion_set.all()”中的问题,它只捕获与此评估方案相关的那些问题。如果您的代码没有这样的行,您将遇到报告的问题。 - krubo


你检查了吗 Django的调查?它非常整洁。


4
2018-06-26 11:01





Django的众包 是django调查的一个分支,从2012年开始积极维护,目标是Django 1.2+。


3
2017-09-17 22:19





不是django专家,所以你可能希望等待一个更有经验的人回答,但你可以尝试这样的事情:

EvaluationQuestions.objects.filter(evaluationscheme__title="myscheme").select_related()

也可以将关系放在另一边,取决于您需要如何访问数据。

class EvaluationScheme(models.Model):
    title = models.CharField(max_length=200)
    evaluations = models.ManyToMany(Evaluation)
    questions = models.ManyToMany(EvaluationQuestions)

1
2018-06-26 11:03