Как я могу создать форму, которая имеет объекты для полей - PullRequest
0 голосов
/ 14 мая 2019

Я создаю приложение списка лидеров, в котором есть объекты Player и Game.Я создал форму, используя свой собственный HTML-код, а не формы Django (выглядит лучше в шаблоне), где вы можете добавить игру, которая берет имя для игрока 1 и игрока 2, и их соответствующие цели.

ЕслиЯ использую ModelForm, он проверяет, что значения действительны, но так как ввод формы - это символы, а в игре объекта модели есть поля для объектов, запрос недействителен.Я пытался выполнить запрос к базе данных, прежде чем попытаться GameForm.is_valid и вручную назначить игроков из базы данных, используя введенные имена пользователей, но я получаю эту ошибку:

That choice is not one of the available choices.</li></ul></li><li>player2<ul class="errorlist"><li>Select a valid choice. That choice is not one of the available choices.</li></ul></li></ul>
[14/May/2019 20:08:04] "POST /elousers/elosearch/ HTTP/1.1" 200 9271

Как я могу сделать это, не делая форму ModelChoiceField?есть ли альтернатива или я должен полностью попробовать другой маршрут.

views.py для формы (над этой формой есть вторая форма, поэтому я предоставил только код для GameForm)

        elif 'addgame' in request.POST:
            data = request.POST.copy()
            try:
                player1 = Player.objects.get(name=data['player1'])
                data['player1'] = player1
            except Player.DoesNotExist:
                render(request, 'elousers/elosearch.html',
                       {'game_display': "Player does not exist yet. Please Register"})
            try:
                player2 = Player.objects.get(name=data['player2'])
                data['player2'] = player2
            except Player.DoesNotExist:
                render(request, 'elousers/elosearch.html',
                       {'game_display': "Player does not exist yet. Please Register"})
            print(data)
            request.POST.data = data
            gameform = GameForm({'player1': data['player1'],
                                 'player2': data['player2'],
                                 'p1goal': data['p1goal'],
                                 'p2goal': data['p2goal'],
                                 })
            print(gameform.errors)
            if gameform.is_valid():
                print("game form was valid")
                gameform.save()
                game_success = messages.success("Game Successfully Added!")
                context2 = {'success': game_success}
                return render(request, 'elousers/elosearch.html', context2)
            else:
                game_invalid = "Invalid entry. Please try again."
                context2 = {'game_display': game_invalid}
                return render(request, 'elousers/elosearch.html', context2)

forms.py

class GameForm(ModelForm):
    player1 = forms.ModelChoiceField(queryset=Player.objects.all())
    p1goal = forms.NumberInput()
    player2 = forms.ModelChoiceField(queryset=Player.objects.all())
    p2goal = forms.NumberInput()

    class Meta:
        model = Game
        fields = (
            'player1',
            'p1goal',
            'player2',
            'p2goal',
        )

    def save(self, commit=True):
        game = super(GameForm, self).save(commit=False)
        game.player1 = self.cleaned_data['player1']
        game.player2 = self.cleaned_data['player2']
        game.p1goal = self.cleaned_data['p1goal']
        game.p2goal = self.cleaned_data['p2goal']
        player1 = Player.objects.get(name=game.player1)
        player2 = Player.objects.get(name=game.player2)
        new_game = Game(player1=player1, player2=player2, p1goal=game.p1goal, p2goal=game.p2goal)
#        new_game.calculate()

        if commit:
            game.save()
#            new_game.save()

        return game

models.py

class Game(models.Model):
    date_played = models.DateTimeField(default=timezone.now)
    player1 = models.ForeignKey(Player, on_delete=models.CASCADE, related_name="+")
    p1goal = models.IntegerField()
    player2 = models.ForeignKey(Player, on_delete=models.CASCADE, related_name="+")
    p2goal = models.IntegerField()

    def __str__(self):
        return str(self.date_played) + " - " + str(self.player1.name) + " " + str(self.p1goal) + " to " + \
               str(self.p2goal) + " " + str(self.player2.name)

HTML в моем шаблоне:

<form method="post" prefix="expected">
            {% csrf_token %}
          <p><input class="w3-input w3-padding-16 w3-threequarter" style="margin-bottom:16px; border-bottom:1px solid black;" type="text" placeholder="Player 1" required name="player1"></p>
          <p><input class="w3-input w3-padding-16 w3-quarter"  style="margin-bottom:16px; border-left:16px solid black;border-bottom:1px solid black;" type="number" placeholder="Goals Scored" required name="p1goal"></p>
          <p><input class="w3-input w3-padding-16 w3-threequarter" style="margin-bottom:16px; border-bottom:1px solid black;" type="text" placeholder="Player 2" required name="player2"></p>
          <p><input class="w3-input w3-padding-16 w3-quarter"  style="margin-bottom:16px; border-left:16px solid black;border-bottom:1px solid black;" type="number" placeholder="Goals Scored" required name="p2goal"></p>
          <p>

Я ожидаю, что форма выдаст trueдля gameform.is_valid() но это не так и выходит рано.Должен ли я использовать forms.form, а не форму модели, чтобы избежать необходимости превращать имена пользователей в Player объекты?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...