首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django-模板调用中的呈现表单_init_() 1额外时间

Django-模板调用中的呈现表单_init_() 1额外时间
EN

Stack Overflow用户
提问于 2016-01-07 11:48:51
回答 1查看 666关注 0票数 2

下面有代码片段,但我的问题总结如下:

当显示具有已知数量的extra窗体(每个表单都需要使用来自另一个对象的数据进行初始化)时,表单的__init__()函数将为窗体集中的每个表单调用,然后再调用一次额外的时间。这会导致错误,因为在上次调用__init__()时,kwargs不包含用于初始化的预期项。

我和我的朋友们玩一个基于电子表格的体育采摘游戏,这是非常乏味的改变。我想学习Django已经有一段时间了,所以我一直致力于将它创建为一个webapp。下面是我的问题的相关模型:

代码语言:javascript
复制
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

我定义了一个与这个模型相关的形式。自定义的__init__()是这样使用来自相关游戏对象的信息初始化表单的,该信息与表单创建中的“初始”参数传递:

代码语言:javascript
复制
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的表单集来扩展这个案例以处理多个表单:

代码语言:javascript
复制
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_list并初始化PickFormSet-我的问题发生在模板中。我让Django来处理渲染,所以现在非常简单:

代码语言:javascript
复制
<form action="{% url 'game_list' week %}" method="post">
    {{ pickforms }}
    <input type="submit" name="pickformset" value="Submit" />
</form>

似乎Django在呈现模板时实际上初始化了PickForms,因为这个问题发生在my PickForm的__init__()中。调试时,我可以逐步完成,因为它为窗体集中的每个表单初始化了一个PickForm --现在总共有6个。因此,对于'form-0‘(我认为是自动生成的前缀)通过'form-5',初始化工作正常,因为kwargs字典中包含一个’初始值‘,正如预期的那样。

但是,在初始化这6种表单之后,它再次遍历__init__(),对于前缀为“form -6”的表单(因此是第7种表单)。此表单没有与其关联的初始数据,因此在__init__()中由于KeyError而出现错误。

为什么Django试图创建另一个表单?我在extra = 5调用中指定了formset_factory,所以总共应该只有6个表单,每个表单都有一个相关的初始数据字典。

我认为这可能与表单集中包含的management_form有关,但是显式地呈现它,然后使用for循环在PickForms上迭代也不起作用--我遇到了相同的问题,模板引擎试图在没有任何初始数据的情况下初始化一个额外的表单。

另外:我尝试使用modelformset_factory并指定PickForm,但是在这种情况下,PickForms的初始化方式似乎有所不同。在kwargs中没有“初始”数据,而是一个“实例”,它的行为有所不同。我对Django还不熟悉,所以我不明白为什么这两种方法会将不同的kwargs传递给PickForm __init__()

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-07 23:19:28

好的,在仔细考虑了一整天之后,我决定在我的__init__()中添加一个try-除了块,以捕获当kwargs没有initial数据时抛出的KeyError。

代码语言:javascript
复制
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)

添加启用了表单集的呈现,我意识到一些(对我来说)在文档中不明显的东西:

除了创建由初始数据定义的任何表单外,还创建了表单集中指定的extra表单的数量。我对这些文档的解释是,我需要足够的extra表单来涵盖我想要用所需数据初始化的许多表单。事后看来,这种引导可能会很烦人--您的initial字典列表可以有不同的长度,而不必担心指定正确的extra,这是很好的。

因此,表单集为字典的initial列表中的每个字典初始化一个表单,然后创建空白表单的extra数量。

我觉得自己很笨,但同时我也不认为这个具体的案例在文档中是那么清楚。

编辑:在仔细阅读时,有一些文本清楚地表明,除了由extra数据生成的表单数量之外,还创建了initial表单。结论:我需要学会阅读。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34654391

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档