Этот ответ дал мне кто-то другой веб-сайт. У него не было желания перепечатывать это здесь, но я буду копировать / вставлять, чтобы принять ответ и для дальнейшего использования.
В представлении, поиск player_id должен быть вызван, даже если данные POST не были отправлены. Это гарантирует, что вы получите 404 в любое время, когда в URL указан неверный player_id. Я просто переместил эту строку кода над IF IF.
Не определяйте форму самостоятельно в шаблоне, когда можете. Это позволяет избежать пропуска полезных вещей, таких как сообщения об ошибках, когда форма недействительна. Django предоставляет несколько отличных инструментов для автоматической генерации HTML-формы. Я обновил форму, чтобы она выглядела следующим образом. ПРИМЕЧАНИЕ: я использовал «form.as_table здесь», но есть некоторые другие полезные методы, такие как «as_p», если вам не нравится вывод HTML в виде таблицы. Вот новый new_stake.html:
<h1> New Play </h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="" method="post">
{% csrf_token %}
<table>{{form.as_table}}</table>
<input type="submit" value="Add New Play" />
</form>
Удалите player_id из вашего класса формы, если он на самом деле не является частью формы (или еще лучше, сделайте его скрытым полем). Кроме того, вам, вероятно, следует использовать здесь ModelForm, которая будет автоматически заполнять элементы формы для вас по большей части после получения данных POST. Тем не менее, я не сделал эту оценку здесь. Что я сделал, так это удалил строку player_id из формы в FORMS.py, так как она уже есть в URL, и, похоже, именно там вы и хотели ее получить (а не скрытый ввод, как предложено выше).
class StakeForm(forms.Form):
stakes = forms.CharField(max_length=200)
amount_won = forms.IntegerField()
last_play_date = forms.DateTimeField()
В этот момент вы должны начать понимать, что вы немного ближе к получению рабочей формы. Проблема, с которой вы столкнулись, заключалась главным образом в том, что ваша форма не прошла проверку is_valid (), и если вы посмотрите на код, это снова показало вам форму. Чтобы все выглядело хуже, вы никогда не знали, что форма недействительна, потому что вы разработали свою собственную форму HTML, которая не содержала сообщений об ошибках. Это исправление стало более очевидным после того, как я использовал {{form}} в шаблоне, а не использовал пользовательский код формы в оригинальном html.
Второе замечание, вы неправильно написали last_play_date как last_played_date. Возможно, это сработало так, как у вас, но чтобы сохранить аналогичное соглашение об именах, я переименовал его в last_play_date, чтобы соответствовать модели.
Последнее замечание о views.py. Вы должны стараться не перенаправлять URL-адрес defiend в виде строки. URL-адреса имеет приятную функцию, которая позволяет вам назвать их. Вы можете использовать функцию reverse (), чтобы выполнить поиск как «reverse» ('sta_added').
Окончательный файл VIEWS.py выглядит следующим образом:
def new_stake(request, player_id):
vars = {}
player = get_object_or_404(Player, pk=player_id)
if request.method == 'POST': # If the form has been submitted
form = StakeForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
stakes = form.cleaned_data['stakes']
amount_won = form.cleaned_data['amount_won']
last_play_date = form.cleaned_data['last_play_date']
stakes_new = Stakes(player=player, stakes=stakes,
amount_won=amount_won, last_play_date=last_play_date)
stakes_new.save()
return HttpResponseRedirect(reverse('stake_added')) # redirect after POST
else:
form = StakeForm() # An unbound form
# Package up some variables to return
vars['player'] = player
vars['form'] = form
context = RequestContext(request)
return render_to_response('stakeme/new_stake.html', vars, context_instance=context)
И для хорошей меры, вот последний URL.py:
urlpatterns = patterns('',
url(r'^(\d+)/new_stake/$', new_stake, name='new_stake'),
url(r'^stake_added/$', direct_to_template, {'template':'stakeme/stake_added.html'}, name="stake_added"),
url(r'^admin/', include(admin.site.urls)),
)