私はDjangoでQuiz
を作成しようとしています。複数の質問とQuestionForm
があります。ビューでは、私はQuestions
のセットを取得し、各オブジェクトのQuestionForm
のリストを作成します。次に、このリストがテンプレートに送られ、テキストとフォームをそれぞれの質問ごとにレンダリングします。フォームのリストからデータを正しく受け取る方法は?
この方法は非常に不快であり、私はそれを行うためのより簡単で直接的な方法がなければならないと思います。
主流:ユーザーがテストをとる場合、Sitting
オブジェクトが
作成されます。このオブジェクトは、ユーザー、クイズ、およびプリロードされた質問に関する情報を保持します。ユーザーがクイズに答えると、質問とユーザーの回答に関する情報を保持するオブジェクトが作成されます(SittingQuestion
)。
ご覧のとおり、各フォームにパラメータname = question-id
を追加しました。各フォームの結果はanswer-id
です。私はIDを解析し、このIDを使ってオブジェクトを作成する必要があります。
特に解析を避けるために助けていただければ幸いです。
私はQuestionForm
とview
を装着しています:
QuestionForm
class QuestionForm(forms.Form):
def __init__(self, question, *args, **kwargs):
super(QuestionForm, self).__init__(*args, **kwargs)
choice_list = [(x.pk, x.text) for x in question.get_answers_list()]
self.fields["question-{}".format(question.id)] = forms.ChoiceField(choices=choice_list,
widget=forms.RadioSelect)
ビュー
def take_quiz(request, id):
if request.method == 'GET':
sitting = models.Sitting.objects.create(quiz=quiz, user=request.user)
sitting.load_questions()
formset = []
for q in sitting.sitting_questions.all():
formset.append((q.question, forms.QuestionForm(q.question)))
return render(request, 'quiz/quiz.html', context={'formset': formset})
quiz = get_object_or_404(models.LanguageQuiz, pk=id)
sitting = get_object_or_404(Sitting,user=request.user,quiz=quiz)
if request.method == 'POST':
for question in request.POST:
question_id = question.split('-')[1]
question_object = get_object_or_404(Question,id=question_id)
answer_id = request.POST[question_id][0]
answer_object = get_object_or_404(Answer,id=answer_id)
SittingQuestion.objects.create(sitting=sitting,question=question_object,answer=answer_object)
MODELS
ここではclass LanguageQuiz(models.Model):
name = models.CharField(max_length=40)
language = models.OneToOneField(sfl_models.Language)
max_questions = models.IntegerField()
time_to_repeat_in_days = models.PositiveIntegerField(default=0)
def __str__(self):
return '{} test'.format(self.name)
def __unicode__(self):
return self.__str__()
class Question(models.Model):
language_quiz = models.ForeignKey(LanguageQuiz,related_name='questions')
text = models.TextField()
def get_answers_list(self):
return self.answers.all()
class Answer(models.Model):
question = models.ForeignKey(Question,related_name='answers',on_delete=models.CASCADE)
text = models.TextField()
correct = models.BooleanField()
class Sitting(models.Model):
user = models.ForeignKey(sfl_models.User, related_name='test_sitting')
quiz = models.ForeignKey(LanguageQuiz)
date_opened = models.DateTimeField(auto_now_add=True)
date_closed = models.DateTimeField(null=True)
closed = models.BooleanField(default=0)
class Meta:
unique_together = ('user','quiz')
def __str__(self):
return 'Sitting - user: {}; quiz: {}'.format(self.user, self.quiz)
def load_questions(self):
questions = random.sample(self.quiz.questions.all(),min(self.quiz.max_questions,len(self.quiz.questions.all())))
for question in questions:
SittingQuestion.objects.create(question=question,sitting=self)
class SittingQuestion(models.Model):
sitting = models.ForeignKey(Sitting, related_name='sitting_questions', on_delete=models.CASCADE)
question = models.ForeignKey(Question, related_name='sitting_questions')
answer = models.ForeignKey(Answer,null=True, blank=True)
ありがとうございますが、それは問題です。私はクイズフォームの中に質問フォームを作成する方法を理解できません。どうぞよろしくお願いいたします。 –
forループを試しましたか?質問の質問のために:choice_list = ...とself.fields ... = forms.ChoiceField ...? また、質問はフォームではなく、クイズフォームのフォームフィールドである必要があります。 –
これはいいですが、もう1つです。私はどのようにラジオ選択の前に各質問のテキストを置くのか分かりません。 {{form}} {%endfor%}のように、質問のテキストを各セットの前に置く方法はありませんが、{{form}} {%endfor%}のようにQuizFormを繰り返し処理できます。私は{%for ....%} {{answer.question.text}}などを試しましたが、何も動作していないようです... –