带有动态窗体的Django FormView
我在下面创建了FormView,它将根据用户所处的流程步骤动态返回一个form类。我在使用带有动态窗体的Django FormView,django,python-3.x,django-class-based-views,Django,Python 3.x,Django Class Based Views,我在下面创建了FormView,它将根据用户所处的流程步骤动态返回一个form类。我在使用get\u form方法时遇到问题。它在get请求中返回正确的表单类,但post请求不起作用 tournament_form_dict = { '1':TournamentCreationForm, '2':TournamentDateForm, '3':TournamentTimeForm, '4':TournamentLocationForm, '5':Tourn
get\u form
方法时遇到问题。它在get请求中返回正确的表单类,但post请求不起作用
tournament_form_dict = {
'1':TournamentCreationForm,
'2':TournamentDateForm,
'3':TournamentTimeForm,
'4':TournamentLocationForm,
'5':TournamentRestrictionForm,
'6':TournamentSectionForm,
'7':TournamentSectionRestrictionForm,
'8':TournamentSectionRoundForm,}
class CreateTournament(FormView):
template_name = 'events/create_tournament_step.html'
def __init__(self, *args, **kwargs):
form_class = self.get_form()
success_url = self.get_success_url()
super(CreateTournament, self).__init__(*args, **kwargs)
def get_form(self, **kwargs):
if 'step' not in kwargs:
step = '1'
else:
step = kwargs['step']
return tournament_form_dict[step]
def get_success_url(self, **kwargs):
if 'step' not in kwargs:
step = 1
else:
step = int(kwargs['step'])
step += 1
if 'record_id' not in kwargs:
record_id = 0
else:
record_id = int(kwargs['record_id'])
return 'events/tournaments/create/%d/%d/' % (record_id, step)
post请求在get\u form
行的django\views\generic\edit.py
失败,我意识到这是因为我在FormView中覆盖了它:
def post(self, request, *args, **kwargs):
"""
Handle POST requests: instantiate a form instance with the passed
POST variables and then check if it's valid.
"""
form = self.get_form()
if form.is_valid(): …
return self.form_valid(form)
else:
return self.form_invalid(form)
但是,当我将自定义get\u form
方法的名称更改为gen\u form
时,如下所示:
def __init__(self, *args, **kwargs):
form_class = self.gen_form()
success_url = self.get_success_url()
super(CreateTournament, self).__init__(*args, **kwargs)
def gen_form(self, **kwargs):
if 'step' not in kwargs:
step = '1'
else:
step = kwargs['step']
return tournament_form_dict[step]
我的表单类在get请求中未得到处理,计算结果为None
。我在挠头,为什么当我重写get\u form
方法时,它能工作,而我自己命名的方法却不能?有人知道该漏洞可能是什么吗?Django的定义是。因此,这里基本上对FormView
进行了子类化,并对get\u form
方法进行了“修补”
您尝试使用gen_form
无效,因为您只定义了局部变量,因此没有多大区别,只有super(…)
调用会产生一些副作用。其他命令将使CPU忙碌一段时间,但在最后,将只为Form
调用Form\u类
变量分配一个引用,但由于它是本地变量,您将丢弃它
也就是说,您的函数包含一些错误。例如,**kwargs
通常最多包含一个参数:form\u class
。因此步骤
s不会有太大作用。您可以通过self.args
和self.kwargs
访问URL参数,并通过self.request.GET
访问查询字符串参数。此外,您可能无论如何都想修补,因为您返回了对类的引用,而不是对初始化表单的引用
通过字符串处理构建URL可能也不是一个好主意,因为如果您(稍微)更改URL模式,那么您可能会忘记替换success\u URL
,因此您将引用一个不再存在的路径。使用是一种更安全的方法,因为您传递视图的名称和参数,然后此函数将“计算”正确的URL。这基本上就是Django模板中{%url…%}
模板标记背后的机制
因此,更好的办法是:
from django.urls import reverse
class CreateTournament(FormView):
template_name = 'events/create_tournament_step.html'
def get_form_class(self):
return tournament_form_dict[self.kwargs.get('step', '1')]
def get_success_url(self):
new_step = int(self.kwargs.get('step', 1)) + 1
# use a reverse
return reverse('name_of_view', kwargs={'step': new_step})
从django.url反向导入
类CreateTournament(FormView):
template_name='events/create_contraction_step.html'
def get_form_类(自我):
返回比赛形式[self.kwargs.get('step','1')]
def get_success_url(自我):
new_step=int(self.kwargs.get('step',1))+1
#用反面
return reverse('name_of_view',kwargs={'step':new_step})
是的,get_表单
是在FormView
中定义的函数,因此使用该函数。事实上,除了super(…)
调用之外,您的\uuuu init\uuu
函数没有做任何事情,因为您只使用局部变量。因此我需要:self.form\u类
它?是的,而且我建议使用reverse
来“计算”URL而不是自己进行列表格式化:好的,谢谢……python/django的某些方面对我来说似乎并不直观……但也许我只是对它了解不够……我会试试看。thanksI发现阅读一些文档很有帮助。对于许多工具来说,文档质量并不高。但我不得不说,写(大多数)Django文档的人做得很好。一段时间后,你会更熟悉Django的“感觉”,因此,一段时间后,你可以“预测”事物是如何设计的。