Django:如何让表单向导在创建表单时接收请求对象?

Posted

技术标签:

【中文标题】Django:如何让表单向导在创建表单时接收请求对象?【英文标题】:Django: How can I make Form Wizard take in a request object when it creates the forms? 【发布时间】:2015-11-24 12:37:33 【问题描述】:

我怎样才能做到,当 Django 的表单工具向导创建我的表单时,它还提供request 对象作为参数?我使用表单工具的主要原因是拥有一个多页表单。现在“正常”创建我的AnswerForm 没有向导,它看起来像

form = AnswerForm(request=request)

我接受request 是因为在表单内部,我想在request.session 中跟踪一个名为'question' 的键。 (此键的目的是确保我可以跟踪与我试图通过此表单创建的Answer 实例相关联的Question 模型实例。我实际上不确定这是否是做到这一点的好方法。提示?)无论如何,现在我收到一个错误,这似乎意味着在我的某处ReviewWizardrequest 不是创建AnswerForm 时的参数。我已经阅读了如何在urls.py 中的向导的as_view() 中使用instance_dict,但我认为在这种情况下它不会有帮助,因为request 对象在urls.py 中不可用。谁能帮我这个?或者你知道一个更好的方法来做我想做的事情吗?谢谢你的帮助!!

(最终,我尝试使用Answersrequest.session 跟踪Questions 的原因是因为我认为当一个人看到的第一个表单出现时,它与表单的实例不同被 POST。由于我的setup() 得到一个随机的Question,它可能与 POST 表单的Question 不匹配,但也许有更好的方法来解决所有这些问题??)

来自urls.py的线路:

url(r'^review_form/', ReviewWizard.as_view([AnswerForm, AnswerForm]), name='review_form'),

这是我的表格:

class AnswerForm(forms.Form):
    answer = forms.CharField(required=True)

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request')
        self.question = None
        self.setup()
        super(AnswerForm, self).__init__(*args, **kwargs)
        self.fields['answer'].label = self.question.question

    def setup(self):
        if "question" in self.request.session:
            self.question = Question.objects.get(id=self.request.session["question"])
        else:
            self.question = get_random_question()
            self.request.session["question"] = self.question.id

    def save(self):
        del self.request.session["question"]
        Answer.objects.create(
            question=self.question,
            author=self.request.user,
            answer=self.cleaned_data['answer']
        )

这是我在views.py 中的向导课程(我从别处复制的):

def process_form_data(form_list):
    form_data = [form.cleaned_data for form in form_list]

    print form_data[0]
    print form_data[1]

    return form_data
class ReviewWizard(SessionWizardView):
    template_name = "review_form.html"

    def done(self, form_list, **kwargs):
        form_data = process_form_data(form_list)

        return render("done.html", "form_data": form_data)

【问题讨论】:

【参考方案1】:

您可以使用 SessionWizardView 中的get_form_kwargs 方法将您的请求添加到表单 kwargs 中。

def process_form_data(form_list):
    form_data = [form.cleaned_data for form in form_list]

    print form_data[0]
    print form_data[1]

    return form_data
class ReviewWizard(SessionWizardView):
    template_name = "review_form.html"

    def done(self, form_list, **kwargs):
        form_data = process_form_data(form_list)

        return render("done.html", "form_data": form_data)

    def get_form_kwargs(self, step):
        kwargs = super(ReviewWizard, self).get_form_kwargs(step)
        kwargs['request'] = self.request
        return kwargs

【讨论】:

啊,这似乎成功了。谢谢!!在旁注中,您如何看待我的整体方法。有没有更好的方法来做到这一点?

以上是关于Django:如何让表单向导在创建表单时接收请求对象?的主要内容,如果未能解决你的问题,请参考以下文章

Django 表单向导 - 将请求传递给视图?

Django 表单向导,当我还没有完成时如何重置/清除向导?

django 表单向导:全局名称“请求”未在 done() 方法中定义

Django 表单向导备份和恢复

Django 表单向导调度程序

django:如何在表单向导中使用 inlineformset?