Ich versuche ein Quiz
in Django zu erstellen. Es gibt mehrere Fragen und QuestionForm
. In einer Ansicht, ich bekomme Questions
Set und erstellen Sie eine Liste von QuestionForm
s für jedes Objekt. Dann wird diese Liste in die Vorlage gesendet und Text und Formular für jede Frage getrennt dargestellt.Wie bekomme ich Daten aus der Liste der Formulare richtig?
Dieser Weg ist sehr unangenehm und ich denke, dass es eine einfachere und direktere Möglichkeit geben muss, dies zu tun.
Der Hauptstrom:
Wenn der Benutzer einen Test in Anspruch nimmt, Sitting
Objekt wird erstellt. Dieses Objekt enthält Informationen über Benutzer, Quiz und vorinstallierte Fragen. Wenn der Benutzer das Quiz beantwortet, werden SittingQuestion
Objekte erstellt, die Informationen über die Frage und die Benutzerantwort enthalten. Wie Sie sehen können, habe ich für jedes Formular einen Parameter name = question-id
hinzugefügt und das Ergebnis jedes Formulars ist answer-id
. Ich muss IDs analysieren und Objekte mit dieser ID erstellen.
Ich würde jede Hilfe schätzen, besonders zu vermeiden, zu analysieren.
Ich bin ein QuestionForm
Anbringen und ein 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)
Ansicht
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
Hierclass 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)
Danke, aber das ist das Problem. Ich kann nicht herausfinden, wie man Frageformen innerhalb der Quizform bildet. Können Sie es bitte erläutern? –
Haben Sie eine for-Schleife ausprobiert? für Fragen in Fragen: ChooseField ...? Auch sollten die Fragen keine Formulare sein, sie sollten Formularfelder der Quizform sein. –
Ja, das ist schön, aber noch eine Sache. Ich kann nicht herausfinden, wie man den Text für jede Frage vor die Radioauswahl stellt. Ich kann über QuizForm wie {% für Antworten im Formular%} {{form}} {% endfor%} iterieren, was Radiobuttons von Antwortsätzen anzeigt, aber es gibt keinen Weg, einen Text der Frage vor jedem Satz zu platzieren. Ich habe versucht {% for ....%} {{answer.question.text}} usw. aber nichts scheint zu funktionieren ... –