Я создаю приложение списка лидеров, в котором есть объекты 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
объекты?