将 Django 模型 + 模型形式组合为一个单元
Combining a Django model + modelform as a single unit
我和我的朋友们通过一个笨拙的电子表格玩了一个体育挑选风格的游戏,我决定通过将游戏实现为一个网络应用程序来学习 Django。我已经完成了 Django 教程,并且一直在研究在数据库、视图和模板之间传递数据的基础知识。
我正在尝试显示来自一个模型的信息以及一个不同的模型表单,然后根据显示的模型将该表单保存到数据库中。这是我的模型:
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)
... other stuff
如您所见,Picks 有一个 Sheet 和一个 Game- 所以一个用户 Sheet 可以有多个 Picks(由于游戏的格式),每个 Game 可以有多次选择(因为多个用户可能会选择任何给定的游戏)。
我的目的是用一个PickForm显示游戏信息,这样用户就可以根据显示的信息进行选择。然后在 POST,选择将适当地外键到正确的游戏。我现在正在试验,因此下面是静态对象 ID:
class GameDetail(DetailView):
model = Game
template_name = 'app/games.html'
context_object_name = 'game_detail'
def get_object(self):
game = get_object_or_404(Game, id=5)
return game
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['pickform'] = PickForm()
return context
def post(request):
form = PickForm(request.POST)
if form.is_valid():
pick = Pick(sheet = form.cleaned_data['sheet'],
game = form.cleaned_data['game'],
amount = form.cleaned_data['amount'],
pick_type = form.cleaned_data['pick_type'],
pick_team = form.cleaned_data['pick_team']
)
pick.save()
return HttpResponseRedirect('/games/')
我想知道的是,我是否应该通过创建一个单独的表单 class 将 PickForm 与游戏相结合来完成此操作?或者将它们动态绑定在一起更有意义?我正在为后者寻找的一个选项是使用 Form.initial 功能并对 get_context_data:
进行以下更改
context['pickform'] = PickForm(initial={'game':self.game})
当我尝试加载页面时出现此错误
AttributeError at /games
'GameDetail' object has no attribute 'game'
在get_context_data()中,get_object()不是已经运行了吗?我以为那是第一个,然后是 get_context_data().
我本可以以完全错误的方式解决这个问题,所以我将非常感谢任何对此问题或我如何构建整个事情的建议。
编辑:我刚刚意识到 self.game 可能只有在它被定义为 GameDetail 顶部的字段时才有效,所以我尝试了这个:
context['pickform'] = PickForm(initial={'game':kwargs['game']})
但这也不管用:
KeyError at /games
'game'
context['pickform'] = PickForm(initial={'game':context['game_detail']})
It returns a dictionary with these contents:
object: The object that this view is displaying (self.object).
在你的表单中你设置了context_object_name = 'game_detail'
我和我的朋友们通过一个笨拙的电子表格玩了一个体育挑选风格的游戏,我决定通过将游戏实现为一个网络应用程序来学习 Django。我已经完成了 Django 教程,并且一直在研究在数据库、视图和模板之间传递数据的基础知识。
我正在尝试显示来自一个模型的信息以及一个不同的模型表单,然后根据显示的模型将该表单保存到数据库中。这是我的模型:
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)
... other stuff
如您所见,Picks 有一个 Sheet 和一个 Game- 所以一个用户 Sheet 可以有多个 Picks(由于游戏的格式),每个 Game 可以有多次选择(因为多个用户可能会选择任何给定的游戏)。
我的目的是用一个PickForm显示游戏信息,这样用户就可以根据显示的信息进行选择。然后在 POST,选择将适当地外键到正确的游戏。我现在正在试验,因此下面是静态对象 ID:
class GameDetail(DetailView):
model = Game
template_name = 'app/games.html'
context_object_name = 'game_detail'
def get_object(self):
game = get_object_or_404(Game, id=5)
return game
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['pickform'] = PickForm()
return context
def post(request):
form = PickForm(request.POST)
if form.is_valid():
pick = Pick(sheet = form.cleaned_data['sheet'],
game = form.cleaned_data['game'],
amount = form.cleaned_data['amount'],
pick_type = form.cleaned_data['pick_type'],
pick_team = form.cleaned_data['pick_team']
)
pick.save()
return HttpResponseRedirect('/games/')
我想知道的是,我是否应该通过创建一个单独的表单 class 将 PickForm 与游戏相结合来完成此操作?或者将它们动态绑定在一起更有意义?我正在为后者寻找的一个选项是使用 Form.initial 功能并对 get_context_data:
进行以下更改context['pickform'] = PickForm(initial={'game':self.game})
当我尝试加载页面时出现此错误
AttributeError at /games
'GameDetail' object has no attribute 'game'
在get_context_data()中,get_object()不是已经运行了吗?我以为那是第一个,然后是 get_context_data().
我本可以以完全错误的方式解决这个问题,所以我将非常感谢任何对此问题或我如何构建整个事情的建议。
编辑:我刚刚意识到 self.game 可能只有在它被定义为 GameDetail 顶部的字段时才有效,所以我尝试了这个:
context['pickform'] = PickForm(initial={'game':kwargs['game']})
但这也不管用:
KeyError at /games
'game'
context['pickform'] = PickForm(initial={'game':context['game_detail']})
It returns a dictionary with these contents:
object: The object that this view is displaying (self.object).
在你的表单中你设置了context_object_name = 'game_detail'