我正在开展一个需要显示测验的测验应用程序 我的模型.py看起来像这样
from django.db import models
from django.contrib.auth.models import User
from django.contrib import admin
#######################
#Quiz Structure Models#
#######################
class Quiz(models.Model):
name = models.CharField(max_length = 255)
creation = models.DateField(auto_now_add=True)
creator = models.ForeignKey(User)
def __unicode__ (self):
return self.name
def possible(self):
total = 0
for question in self.question_set.all():
question.save()
total += question.value
return total
class Question(models.Model):
question = models.CharField(max_length = 255)
quiz = models.ForeignKey(Quiz)
creator = models.ForeignKey(User)
creation = models.DateField(auto_now_add = True)
#objective = TODO: include standards linking in later versions
value = models.IntegerField(default = 1)
def __unicode__(self):
return self.question
class Answer(models.Model):
answer = models.CharField(max_length = 255)
question = models.ForeignKey(Question)
is_correct = models.BooleanField(default = False)
#Creator is tied to the quiz
##########
#Attempts#
##########
class QuizAttempt(models.Model):
student = models.ForeignKey(User)
quiz = models.ForeignKey(Quiz)
date = models.DateField(auto_now_add = True)
#Score Method (similar to possible in Quiz
class QuestionAttempt(models.Model):
attempt = models.ForeignKey(QuizAttempt)
question = models.ForeignKey(Question)
response = models.ForeignKey(Answer)
#######
#Admin#
#######
class QuestionInline(admin.StackedInline):
model = Question
extra = 2
class AnswerInline(admin.StackedInline):
model = Answer
extra = 2
class QuizAdmin(admin.ModelAdmin):
list_display = ('name', 'creator', 'creation', 'possible',)
search_fields = ('name', 'creator')
inlines = [QuestionInline]
admin.site.register(Quiz, QuizAdmin)
class QuestionAdmin(admin.ModelAdmin):
inlines = [AnswerInline]
search_fields = ('question', 'quiz', 'value',)
list_display = ('question', 'quiz', 'value',)
admin.site.register(Question, QuestionAdmin)
我正在尝试构建一个表单或表单集,让我有一个包含所有问题的测验尝试的表单,所以它看起来像这样,并且让我回过头去看看保存学生尝试进行测验。
到目前为止,看起来我最好的解决方案是使用这些模型构建一个formset,但我不确定如何指定我的选择以将其限制为与当前问题相关的答案,或者如何获得正确的formset在一个视图中。
答案 0 :(得分:4)
如果我正确理解您的问题,您可能希望在执行时创建自定义Form
,以及许多自定义Field
。我期待的是:
class QuizForm(forms.Form):
def __init__(self, data, questions, *args, **kwargs):
self.questions = questions
for question in questions:
field_name = "question_%d" % question.pk
choices = []
for answer in question.answer_set().all():
choices.append((answer.pk, answer.answer,))
## May need to pass some initial data, etc:
field = forms.ChoiceField(label=question.question, required=True,
choices=choices, widget=forms.RadioSelect)
return super(QuizForm, self).__init__(data, *args, **kwargs)
def save(self):
## Loop back through the question/answer fields and manually
## update the Attempt instance before returning it.
可能需要额外调整才能通过管理界面完成这项工作,但这应该为您在执行时构建表单本身提供了良好的开端。
您的观点可能类似于:
# Assuming something like: /quiz/69/ with "69" being the quiz PK.
def render_quiz(request, quiz_id):
quiz = get_object_or_404(Quiz, quiz_id)
form = QuizForm(questions=quiz.question_set.all())
if request.method == "POST":
form = QuizForm(request.POST, questions=quiz.question_set.all())
if form.is_valid(): ## Will only ensure the option exists, not correctness.
attempt = form.save()
return redirect(attempt)
return render_to_response('quiz.html', {"form": form})
答案 1 :(得分:1)
这是一个如何运作的粗略概念。
# define a form
class QuestionForm(forms.Form):
id = forms.IntegerField(widget=forms.HiddenInput) # make it hidden- i know, not very elegant
question = forms.CharField()
answer = forms.CharField()
# views.py
def display(request):
quiz = Quiz.objects.get(creator=request.user) # or some definition of quiz
questions = quiz.question_set.all().values('id','question') # to get question text
# define a formset
QuestionFormSet = formset_factory(QuestionForm)
# add initial data
formset = QuestionFormSet(initial=questions)
# should work because the field names are the same as that of form
if request.method == 'POST':
formset = QuestionFormSet(request.POST)
if formset.is_valid():
# associate answers here, note that you have access to the question id,
# which is a hidden field in your form