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()

Мне удалось исправить это самостоятельно, и я делюсь здесь решением:

  1. Я изменил поле формы с ModelMultipleChoiceField на ModelChoiceField. ModelMultipleChoiceField предназначено для полей модели отношений ManyToMany, в то время как мое поле является ForeignKey. Я также удалил метод init:
squad_to_player = forms.ModelChoiceField(queryset=AvailablePlayer.objects.all())
  1. Вид был довольно запутанным, о чем я знал, но после исправления вышеописанного, у меня начали появляться журналы ошибок, так что в итоге я смог прийти к следующему решению:

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)
Вернуться на верх