Python Django-在模板中呈现formset会额外调用form _init_1()
下面是我的代码片段,但我的问题总结如下: 当显示具有已知数量的Python Django-在模板中呈现formset会额外调用form _init_1(),python,django,django-forms,django-templates,Python,Django,Django Forms,Django Templates,下面是我的代码片段,但我的问题总结如下: 当显示具有已知数量的额外表单的表单集时,每个表单都需要使用来自另一个对象的数据进行初始化,表单集中的每个表单都会调用表单的\u init\u()函数,然后再额外调用一次。这会导致错误,因为上次调用\uuuu init\uuu()时,kwargs不包含用于初始化的预期项。 我和我的朋友们玩一个基于电子表格的运动选秀游戏,对其进行更改非常乏味。我想学习Django已经有一段时间了,所以我一直致力于将其创建为一个webapp。以下是我的问题的相关模型: cla
额外
表单的表单集时,每个表单都需要使用来自另一个对象的数据进行初始化,表单集中的每个表单都会调用表单的\u init\u()
函数,然后再额外调用一次。这会导致错误,因为上次调用\uuuu init\uuu()
时,kwargs不包含用于初始化的预期项。
我和我的朋友们玩一个基于电子表格的运动选秀游戏,对其进行更改非常乏味。我想学习Django已经有一段时间了,所以我一直致力于将其创建为一个webapp。以下是我的问题的相关模型:
class Pick(models.Model):
sheet = models.ForeignKey(Sheet)
game = models.ForeignKey(Game)
HOME = 'H'
AWAY = 'A'
PICK_TEAM_CHOICES = (
(HOME, 'Home'),
(AWAY, 'Away'),
)
pick_team = models.CharField(max_length=4,
choices=PICK_TEAM_CHOICES,
default=HOME)
... other stuff
我已经定义了一个与这个模型相关的表单。自定义的\uuuuu init\uuuuuu()
使用来自相关游戏对象的信息初始化表单,并在表单创建中使用“initial”参数传递:
class PickForm(ModelForm):
class Meta:
model = Pick
widgets = {'game': forms.HiddenInput()}
fields = ['sheet','game','amount','pick_type','pick_team']
def __init__(self, *args, **kwargs):
game = kwargs['initial']['game']
super(PickForm, self).__init__(*args, **kwargs)
self.fields['pick_team'].choices = ( ('H', game.home_team), ('A', game.away_team), )
我最近创建了一个“原子”案例,用户可以通过相关模板中的PickForm来选择游戏,该表单在一个基于类的视图的post()方法中处理。我试图通过创建一组PickForms来扩展此案例以处理多个表单:
class GameList(ListView):
template_name = 'app/games.html'
context_object_name = 'game_list'
def get_queryset(self):
games = get_list_or_404(Game, week = self.kwargs['week'])
return games
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
#create a formset of PickForms
PickFormSet = formset_factory(PickForm, extra = len(context['game_list'])-1)
pick_list = []
sheet = Sheet.objects.get(user=self.request.user,league_week=self.kwargs['week'])
picks = Pick.objects.filter(sheet = sheet)
for index, game in enumerate(context['game_list'],start=0):
#logic to create a list of objects for initial data
#create the formset with the pick dictionary
context['pickforms'] = PickFormSet(initial=[{'game':pick.game,
'sheet':pick.sheet,
'amount':pick.amount,
'pick_type':pick.pick_type,
'pick_team':pick.pick_team,} for pick in pick_list])
return context
视图中的get_context_data()正确构造pick_列表并初始化PickFormSet-我的问题发生在模板中。我让Django处理渲染,因此现在非常简单:
<form action="{% url 'game_list' week %}" method="post">
{{ pickforms }}
<input type="submit" name="pickformset" value="Submit" />
</form>
{{pickforms}}
Django似乎在呈现模板时实际初始化了PickForms,因为问题发生在我的PickForm的\uuu init\uuuu()
中。调试时,我可以单步执行,因为它为表单集中的每个表单初始化一个PickForm-现在总共有6个。因此,对于“form-0”(我认为是自动生成的前缀)到“form-5”,初始化工作正常,因为kwargs字典像预期的那样包含一个“initial”
但是,在初始化这6个表单之后,对于前缀为“form-6”的表单(也就是第7个表单),它会再次循环执行\uuu init\uuu()
)。此表单没有与之关联的初始数据,因此由于键错误,在\uuuu init\uuuu()
中出错
为什么Django试图创建另一个表单?我在formset\u工厂调用中指定了extra=5
,因此总共应该只有6个表单,每个表单都有一个相关的初始数据字典
我认为这可能与表单集包含的管理表单有关,但是显式呈现该表单,然后使用for循环迭代PickForms也不起作用-我遇到了相同的问题,模板引擎试图在没有任何初始数据的情况下初始化额外表单
另外:我尝试使用modelformset_工厂并指定PickForm,但是在这种情况下,PickForms的初始化方式似乎有所不同。kwargs中没有“初始”数据,而是一个“实例”,其行为不同。我还是Django的新手,所以我不明白为什么这两种方法会将不同的Kwarg传递给PickForm
\uuuu init\uuuu()
好吧,在考虑了一整天之后,我决定在我的\uuu init\uuu()中添加一个try-except块
仅捕获当kwargs
没有初始数据时抛出的KeyError
def __init__(self, *args, **kwargs):
try:
game = kwargs['initial']['game']
super(PickForm, self).__init__(*args, **kwargs)
self.fields['pick_team'].choices = ( ('H', game.home_team),('A', game.away_team), )
except KeyError:
super(PickForm, self).__init__(*args, **kwargs)
添加该选项启用了表单集的呈现,我意识到(对我来说)文档中没有明显的东西:
除了初始数据定义的任何表格之外,还创建了表格集中指定的额外表格的数量。我对文档的理解是,我需要足够的额外的表单来覆盖我想要用所需数据初始化的表单。事后看来,这类簿记可能会让人恼火——你的初始
词典列表长度可以不同,而不必担心指定正确的额外
,这是很好的
因此,表单集为initial
词典列表中的每个词典初始化一个表单,然后创建extra
数量的空白表单
我觉得自己很傻,但同时我认为这个具体案例在文档中并没有那么清楚
编辑:仔细阅读,有一些文字清楚地表明,除了由初始
数据生成的表格数量之外,还创建了额外
表格。结论:我需要学习阅读好吧,经过一整天的思考,我决定在我的\uuuu init\uuuu()
中添加一个try except块,以捕获当kwargs
没有初始
数据时抛出的keyrerror
def __init__(self, *args, **kwargs):
try:
game = kwargs['initial']['game']
super(PickForm, self).__init__(*args, **kwargs)
self.fields['pick_team'].choices = ( ('H', game.home_team),('A', game.away_team), )
except KeyError:
super(PickForm, self).__init__(*args, **kwargs)
添加该选项启用了表单集的呈现,我意识到(对我来说)文档中没有明显的东西:
除了初始数据定义的任何表格之外,还创建了表格集中指定的额外表格的数量。我对文档的理解是,我需要足够的额外的表单来覆盖我想要用所需数据初始化的表单。事后看来,这类簿记可能会让人恼火——你的初始
词典列表长度可以不同,而不必担心指定正确的额外
,这是很好的
因此,表单集为initial
词典列表中的每个词典初始化一个表单,然后创建extra
数量的空白表单
我觉得自己很傻,但同时我认为这个具体案例在文档中并没有那么清楚
编辑:仔细阅读,有一些文字清楚地表明,除了由初始
数据生成的表格数量之外,还创建了额外
表格。结论:我需要学习阅读