Django Form не обновляет данные в модели
Это мой первый проект 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()
Вот файл представления, в котором, как мне кажется, что-то упущено/неправильно:
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>
В отрендеренном html правильно отображается форма с выпадающим меню, правильно заполненная объектами в базе данных из модели "AvailablePlayer", однако при выборе одного и нажатии на кнопку "Add" ничего не происходит, и выбранный игрок не добавляется в БД.
Заранее благодарю вас за уделенное время.
Основываясь на 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)