将 ForeignKeyed 对象中的字段值用于 ModelChoiceFields
Using field values from a ForeignKeyed object for ModelChoiceFields
我和我的朋友们玩了一个基于电子表格的运动选择游戏,更改起来非常繁琐。我想学习 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_team
和 away_team
?目前它默认为 'Home' 和 'Away'.
我知道这是一个核心的常见问题 - 如何在下拉列表中显示外键信息,但是我找到的所有答案都可以向 ModelChoiceField 提供查询集,因为它们通常试图列出来自每个对象(或某些过滤子集)的字段。在这种情况下,我只想列出 2 个字段,并且只来自一个对象。
我尝试返回一个由 kwargs 中已经存在的 Game 对象组成的查询集,但它只在下拉列表中显示游戏的 str() 方法,并试图优化查询集使用相关字段名称也不起作用。
编辑:我意识到实际上使用 Game
对象中的 home_team
和 away_team
值在保存 Pick
时需要额外的处理,或者可能更难比起那个来说。有什么办法可以单独在模板中进行这种别名处理吗?与选择字段的方式类似,我可以使用 get_pick_team_display
来显示更好看的显示值('Home'、'Away'),而不是模糊的 'H' 或 'A'。
EDIT2:查看代码
class 游戏细节(细节视图):
#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
这是一种快速修复方法。在您的 __init__
中,不要重新分配 pick_team
字段,只需重新定义其选项如下:
self.fields['pick_team'].choices = (
('H', game.home_team),
('A', game.away_team),
)
我和我的朋友们玩了一个基于电子表格的运动选择游戏,更改起来非常繁琐。我想学习 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_team
和 away_team
?目前它默认为 'Home' 和 'Away'.
我知道这是一个核心的常见问题 - 如何在下拉列表中显示外键信息,但是我找到的所有答案都可以向 ModelChoiceField 提供查询集,因为它们通常试图列出来自每个对象(或某些过滤子集)的字段。在这种情况下,我只想列出 2 个字段,并且只来自一个对象。
我尝试返回一个由 kwargs 中已经存在的 Game 对象组成的查询集,但它只在下拉列表中显示游戏的 str() 方法,并试图优化查询集使用相关字段名称也不起作用。
编辑:我意识到实际上使用 Game
对象中的 home_team
和 away_team
值在保存 Pick
时需要额外的处理,或者可能更难比起那个来说。有什么办法可以单独在模板中进行这种别名处理吗?与选择字段的方式类似,我可以使用 get_pick_team_display
来显示更好看的显示值('Home'、'Away'),而不是模糊的 'H' 或 'A'。
EDIT2:查看代码 class 游戏细节(细节视图): #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
这是一种快速修复方法。在您的 __init__
中,不要重新分配 pick_team
字段,只需重新定义其选项如下:
self.fields['pick_team'].choices = (
('H', game.home_team),
('A', game.away_team),
)