【问题标题】:How to Validate and Compare Data against the Database in DetailView - Django如何在 DetailView 中根据数据库验证和比较数据 - Django
【发布时间】:2020-03-27 07:13:33
【问题描述】:

我有一个 ChallengeDetailView,它显示挑战的详细信息,例如博客文章。我在同一页面上还有一个表单字段,它应该得到挑战的答案,并将其与数据库进行比较。到目前为止,这是我所做的;

class ChallengeDetailView(DetailView):
    model = Challenge

    def get_context_data(self, **kwargs):
        context = super(ChallengeDetailView, self).get_context_data(**kwargs)
        context['form'] = FlagForm
        return context
from django import forms


class FlagForm(forms.Form):
    flag = forms.CharField(label='Challenge Flag',required=True)
class FlagFormView(FormView):
    form_class = FlagForm
    success_url = reverse_lazy('challenge-detail')

我尝试实现如下的简单逻辑;

def get_flag(self, request):
    if self.request.method == 'POST':
        form = FlagForm(request.POST)
        if form.is_valid():
            flag = form.cleaned_data.get('flag')
            if flag == Challenge.flag:
                return messages.success("You found the flag!")
    else:
        return FlagForm()

我试图将其包含在 form_valid() 方法中,但无法使其在 ChallengeDetailView 中工作。我愿意接受任何建议。我来自 Symfony 背景,对 Django 很陌生。

【问题讨论】:

  • 你能添加你的 FlagForm 类吗?
  • 对不起,我错过了。更新了问题。谢谢你的提醒。 @JPG
  • 首先,你可以在这里使用Django's ModelForm class,它更适合机型。因此,我建议用 ModelForm 重写 FlagForm 并在 Form 类本身中编写适当的 validation functions
  • 按照您提供的文档进行操作,但现在当我发送表单时出现 405 错误。我认为这是因为细节视图中不允许使用 POST 方法。是否有正确的方法可以在 detailview 上启用 POST 方法,或者它违反了良好做法? @JPG
  • 是的..你是对的。您需要将UpdateView 与 DetailView 一起使用。

标签: django django-forms django-views django-database


【解决方案1】:

我终于弄明白了。 我在 forms.py 中创建了一个常规表单

from django import forms

class FlagForm(forms.Form):
    flag = forms.CharField()

在views.py 中,我有一个带有SingleObjectMixin 的详细视图和表单视图来处理当前的帖子。

class ChallengeDisplay(DetailView):
model = Challenge

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['form'] = FlagForm()
    return context

使用 SingleObjectMixin 的表单视图;

class ChallengeFormEntry(SingleObjectMixin, FormView):
    template_name = 'ctf/challenge_detail.html'
    form_class = FlagForm
    model = Challenge

def post(self, request, *args, **kwargs):
    if request.method == 'POST':
        form = FlagForm(request.POST)
        if form.is_valid():
            flag = form.cleaned_data.get('flag')
            if self.get_object().flag == flag:
                messages.success(request, 'good job!')
            else: messages.warning(request, 'Try again!')
    form = FlagForm()
    return super().post(request, *args, **kwargs)

def get_success_url(self):
    return reverse('challenge-detail', kwargs={'pk': self.get_object().pk, 'slug':self.get_object().slug})

【讨论】:

    猜你喜欢
    • 2019-05-13
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2023-01-31
    • 2022-01-04
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    相关资源
    最近更新 更多