Django Form 不更新模型中的数据
Django Form not updating data in the model
这是我的第一个 Django 项目,我被卡住了。如果不是解决方案,但只是提示我做错了什么,将不胜感激。
我有一个模型,其中一个属性默认设置为 Null,我想使用一个表单来更新该属性,其中的 ID 取自另一个模型。
这些是 2 个模型:
models.py
class Squad(models.Model):
squad_name = models.CharField(max_length=20)
def __str__(self):
return self.squad_name
class AvailablePlayer(models.Model):
player_name = models.CharField(max_length=25)
squad = models.ForeignKey(Squad, on_delete=models.CASCADE, blank=True, null=True)
def __str__(self):
return self.player_name
这是表格:
forms.py
class AddSquadToPlayerForm(forms.Form):
# squad the player will be added to
squad_to_player = forms.ModelMultipleChoiceField(queryset=None)
def __init__(self, *args, **kwargs):
super(AddSquadToPlayerForm, self).__init__()
self.fields['squad_to_player'].queryset = AvailablePlayer.objects.all()
这是视图文件,我认为其中有些东西 missing/wrong:
views.py
def add_player_to_squad(request, squad_id):
# player = AvailablePlayer.objects.get(id=squad_id)
squad = Squad.objects.get(id=squad_id)
if request.method == "POST":
form = AddPlayerToSquadForm(request.POST)
if form.is_valid():
form.squad = form.cleaned_data['id']
form.save()
return redirect('fanta_soccer_app:squad', squad_id=squad_id)
else:
form = AddPlayerToSquadForm(queryset=AvailablePlayer.objects.all())
context = {"squad": squad, "form": form}
return render(request, 'fanta_soccer_app/add_player.html', context)
最后,这是 html 文件
add_player.html
<body>
<p>Add a new player to the Squad:</p>
<p><a href="{% url 'fanta_soccer_app:squad' squad.id %}">{{ squad }}</a></p>
<form action="{% url 'fanta_soccer_app:add_player' squad.id %}" method="POST">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<button name="submit" type="submit" >Add player</button>
</form>
</body>
The rendered html shows correctly a form with a drop down menu correctly populated with the objects in the database from the "AvailablePlayer" model, however when selecting one and clicking on "Add", nothing happens,并且所选玩家未添加到数据库中。
提前感谢您的宝贵时间。
编辑:views.py 中的代码已根据评论进行了修改
附加信息:为确认数据库正常工作,如果我手动将 squad_id 添加到数据库中的可用玩家之一,它将在小队详细信息视图中正确列出。
基于 docs 我认为你出错的地方是你试图更新现有值,这需要你将实例关键字参数传递给 form.save()
.
所以我认为你需要做这样的事情:
if form.is_valid():
a = Squad.objects.get(id=squad_id)
form = AddSquadToPlayerForm(request.POST, instance=a)
form.squad = form.cleaned_data['id']
form.save()
我自己解决了,这里分享一下解决方法:
- 我将表单字段从 ModelMultipleChoiceField 更改为 ModelChoiceField。 ModelMultipleChoiceField 用于 ManyToMany 关系模型字段,而我的是 ForeignKey。我还删除了 init 方法:
squad_to_player = forms.ModelChoiceField(queryset=AvailablePlayer.objects.all())
- 据我所知,视图非常混乱,但在修复上述问题后,我开始出现错误日志,因此我最终可以提出以下解决方案:
view.py
def add_player_to_squad(request, squad_id):
squad = Squad.objects.get(id=squad_id)
if request.method == "POST":
form = AddPlayerToSquadForm(request.POST)
if form.is_valid():
player_to_sign = form.cleaned_data['squad_to_player']
player_to_sign.squad = squad
player_to_sign.save()
return redirect('fanta_soccer_app:squad', squad_id=squad_id)
else:
form = AddPlayerToSquadForm()
context = {"squad": squad, "form": form}
return render(request, 'fanta_soccer_app/add_player.html', context)
这是我的第一个 Django 项目,我被卡住了。如果不是解决方案,但只是提示我做错了什么,将不胜感激。
我有一个模型,其中一个属性默认设置为 Null,我想使用一个表单来更新该属性,其中的 ID 取自另一个模型。 这些是 2 个模型:
models.py
class Squad(models.Model):
squad_name = models.CharField(max_length=20)
def __str__(self):
return self.squad_name
class AvailablePlayer(models.Model):
player_name = models.CharField(max_length=25)
squad = models.ForeignKey(Squad, on_delete=models.CASCADE, blank=True, null=True)
def __str__(self):
return self.player_name
这是表格:
forms.py
class AddSquadToPlayerForm(forms.Form):
# squad the player will be added to
squad_to_player = forms.ModelMultipleChoiceField(queryset=None)
def __init__(self, *args, **kwargs):
super(AddSquadToPlayerForm, self).__init__()
self.fields['squad_to_player'].queryset = AvailablePlayer.objects.all()
这是视图文件,我认为其中有些东西 missing/wrong:
views.py
def add_player_to_squad(request, squad_id):
# player = AvailablePlayer.objects.get(id=squad_id)
squad = Squad.objects.get(id=squad_id)
if request.method == "POST":
form = AddPlayerToSquadForm(request.POST)
if form.is_valid():
form.squad = form.cleaned_data['id']
form.save()
return redirect('fanta_soccer_app:squad', squad_id=squad_id)
else:
form = AddPlayerToSquadForm(queryset=AvailablePlayer.objects.all())
context = {"squad": squad, "form": form}
return render(request, 'fanta_soccer_app/add_player.html', context)
最后,这是 html 文件
add_player.html
<body>
<p>Add a new player to the Squad:</p>
<p><a href="{% url 'fanta_soccer_app:squad' squad.id %}">{{ squad }}</a></p>
<form action="{% url 'fanta_soccer_app:add_player' squad.id %}" method="POST">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<button name="submit" type="submit" >Add player</button>
</form>
</body>
The rendered html shows correctly a form with a drop down menu correctly populated with the objects in the database from the "AvailablePlayer" model, however when selecting one and clicking on "Add", nothing happens,并且所选玩家未添加到数据库中。
提前感谢您的宝贵时间。
编辑:views.py 中的代码已根据评论进行了修改
附加信息:为确认数据库正常工作,如果我手动将 squad_id 添加到数据库中的可用玩家之一,它将在小队详细信息视图中正确列出。
基于 docs 我认为你出错的地方是你试图更新现有值,这需要你将实例关键字参数传递给 form.save()
.
所以我认为你需要做这样的事情:
if form.is_valid():
a = Squad.objects.get(id=squad_id)
form = AddSquadToPlayerForm(request.POST, instance=a)
form.squad = form.cleaned_data['id']
form.save()
我自己解决了,这里分享一下解决方法:
- 我将表单字段从 ModelMultipleChoiceField 更改为 ModelChoiceField。 ModelMultipleChoiceField 用于 ManyToMany 关系模型字段,而我的是 ForeignKey。我还删除了 init 方法:
squad_to_player = forms.ModelChoiceField(queryset=AvailablePlayer.objects.all())
- 据我所知,视图非常混乱,但在修复上述问题后,我开始出现错误日志,因此我最终可以提出以下解决方案:
view.py
def add_player_to_squad(request, squad_id):
squad = Squad.objects.get(id=squad_id)
if request.method == "POST":
form = AddPlayerToSquadForm(request.POST)
if form.is_valid():
player_to_sign = form.cleaned_data['squad_to_player']
player_to_sign.squad = squad
player_to_sign.save()
return redirect('fanta_soccer_app:squad', squad_id=squad_id)
else:
form = AddPlayerToSquadForm()
context = {"squad": squad, "form": form}
return render(request, 'fanta_soccer_app/add_player.html', context)