【发布时间】:2020-06-02 14:44:09
【问题描述】:
概述: 我想建立一个问答网站,用户必须为每个问题输入正确的答案。为此我制作了 3 个模型:
class ProblemSet(models.Model):
id = models.IntegerField(primary_key=True)
class Problem(models.Model):
id = models.IntegerField(primary_key=True)
problem_set = models.ForeignKey(ProblemSet, on_delete=models.CASCADE)
question = models.TextField()
solution = models.TextField()
class Solve(models.Model):
username = models.ForeignKey(User, on_delete=models.CASCADE)
problem_set = models.ForeignKey(ProblemSet, on_delete=models.CASCADE)
problem_id = models.ForeignKey(Problem, on_delete= models.CASCADE)
在求解模型中,如果有任何条目表示特定用户已解决该问题 ID。 所以,我使用了通用的表单视图:
class IndexView(FormView):
form_class = ProblemForm
template_name = 'home/index.html'
success_url = reverse_lazy('index')
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
if self.request.user.is_authenticated:
inner_qs = "fetch ids that are solved from Solve model"
problem_obj = Problem.objects\
.exclude(id__in=inner_qs)\
.order_by('id').first()
else:
#do something
context['question'] = problem_obj.question
return context
问题形式为:
from django import forms
class ProblemForm(forms.Form):
solution = forms.CharField(widget=forms.TextInput())
如何验证用户输入的答案是否正确?我确实在 def form_valid(self, form) 函数中获得了 solution 字段的值,但我应该如何处理呢?我应该在 context 中传递 question_id 并在 form_valid 中查询数据库,还是应该将解决方案本身传递给 context 并在 form_valid() 方法中访问上下文数据以防止双重查询,但在这种方法中,我不确定这是否安全,因为我不不希望将解决方案传递给客户。
有什么优雅的方法吗?
附:在将用户输入的解决方案与该问题的数据库中的解决方案进行比较后,我在 Solve 表中添加一个条目,表示该特定用户已解决问题 ID。
【问题讨论】:
-
我会做一个 javascript AJAX 请求。如果您将解决方案传递给带有问题的页面,用户只需检查页面源即可获得正确答案。如果你关心这一点,如果用户在荣誉系统上,这可能不是一个大问题。
-
两个选项: 1. 将
problem_id作为隐藏输入字段添加到表单(您可以覆盖get_initial()以预先填充该字段),以便在提交时提交他的答案。用户可以根据需要对其进行操作,但我看不到对用户有任何好处,即。没有安全问题。 2. 由于problem_id在用户没有解决问题的情况下不会改变,你可以在form_valid的情况下再次获取它。为避免多次获取它(您需要在 get_context_data 中使用它),请创建一个新方法get_problem并将值分配给self,以便它在已定义或获取它时返回它。 -
@dirkgroten 看起来这是唯一的选择......我想避免在 form_valid() 函数中再次查询问题表。
-
@Waterbyte 无论您选择哪个选项,您都必须同时查询 GET 和 POST。无论如何,这些都是两个独立的 HTTP 请求,原则上(就您的代码而言)彼此无关。但是您只需要对每个请求进行 一次查询。
-
@dirkgroten 是的,但我不想在 POST 请求中查询问题表,仅解决表。而且我不想像 Mikeh 建议的那样将解决方案传递给页面。
标签: django django-forms