使用来自ForeignKeyed对象的ModelChoiceFields

时间:2015-12-13 17:38:01

标签: django django-models django-forms

我的朋友和我玩一个基于电子表格的体育采摘游戏,这对于进行更改非常繁琐。我想学习Django一段时间,所以我一直在努力创建它作为webapp。以下是我正在使用的模型:

class Sheet(models.Model):
user = models.ForeignKey(User)
... other stuff

class Game(models.Model):
home_team = models.CharField(max_length=100, default='---')
away_team = models.CharField(max_length=100, default='---')
... other stuff

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

现在,我正试图用一种简单的方法来显示以下表单,其中包含来自外键模型而非pick_team默认选项的信息。 game被隐藏,因为它通过使用视图中的initial功能与生成的PickForm配对。

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']=forms.ModelChoiceField([game.away_team,game.home_team])

据我所知,ModelChoiceField需要一个查询集 - 所以当我提供一个列表或一个元组时,我得到一个'list' object has no attribute 'iterator'错误。现在了解这一点,如何在模板的pick_team下拉列表中显示游戏字段home_teamaway_team?目前,它默认为“家庭'和'离开'。

我知道这是一个常见的核心问题 - 如何在下拉列表中显示ForeignKeyed信息,但是我发现的所有答案都适用于向ModelChoiceField提供查询集,因为他们通常会尝试列出每个对象(或一些过滤子集)的字段。在这种情况下,我只想列出2个字段,并且只列出一个对象。

我尝试返回一个由已存在于kwargs中的Game对象组成的查询集,但它只是在下拉列表中显示游戏的 str ()方法,并尝试使用相关的字段名称也不起作用。

编辑:我意识到实际使用home_team对象中的away_teamGame值需要额外处理以保存Pick,或者可能比这更难处理。有没有办法在模板中单独进行这种别名?与选择字段的方式类似,我可以使用get_pick_team_display来显示更好看的显示值(' Home',#39; Away')而不是模糊的' H&# 39;或者' A'。

EDIT2:查看代码     class GameDetail(DetailView):     #model =游戏     template_name =' app / games.html'     context_object_name =' game_detail'

def get_object(self):
    game = get_object_or_404(...object filtering)
    return game

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    try:
        pick = Pick.objects.get(game=context['game_detail'],
     ....other stuff)

        context['pickform'] = PickForm(initial={'game':context['game_detail'],
     .... other stuff
    except Pick.DoesNotExist:
        #pick = none
        context['pickform'] = PickForm(initial={'game':context['game_detail'],
                                            })

    return context

def post(self, request, *args, **kwargs):
    form = PickForm(request.POST)
    if form.is_valid():
        ....process form

1 个答案:

答案 0 :(得分:1)

这是一种quickfix方法。在__init__,而不是重新分配pick_team字段,只需重新定义其选项,如下所示:

self.fields['pick_team'].choices = (
    ('H', game.home_team),
    ('A', game.away_team),
)