如何创建包含字段对象的表单

时间:2019-05-14 20:15:56

标签: python html django

我正在创建一个包含PlayerGame对象的排行榜应用。我使用自己的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>

我希望该表单为gameform.is_valid()生成true,但事实并非如此,并且提早退出。我应该使用forms.form而不是模型形式来避免被迫将用户名变成Player对象吗?

0 个答案:

没有答案