I’m trying to carry over player_id and save to the Stakes table referencing that player_id, which is the foreign key for the Stakes table. However, I am not sure how to do so. I have edited my views.py to reflect two of the answers below, but it still seems to refresh the form and not save to the database. The only thing I can think of is this being due to the DateTimeField. However, I am using a copy/pasted date from the database in the exact format so I doubt that would be it.
Models.py
class Player(models.Model):
user_name = models.CharField(max_length=200)
real_name = models.CharField(max_length=200)
SITE_CHOICES = (
('FTP', 'Full Tilt Poker'),
('Stars', 'Pokerstars'),
('UB', 'Ultimate Bet'),
)
site_played = models.CharField(max_length=5, choices=SITE_CHOICES)
class Stakes(models.Model):
player = models.ForeignKey(Player)
stakes = models.CharField(max_length=200)
amount_won = models.DecimalField(max_digits=12, decimal_places=2)
last_play_date = models.DateTimeField('Date Last Updated')
Views.py
def new_stake(request, player_id):
if request.method == 'POST': # If the form has been submitted
player = get_object_or_404(Player, pk=player_id)
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_played_date = form.cleaned_data['last_played_date']
stakes_new = Stakes(player = player,
stakes = stakes,
amount_won = amount_won,
last_played_date = last_played_date)
stakes_new.save()
return HttpResponseRedirect('/stakeme/stake_added/') # redirect after POST
else:
form = StakeForm() # An unbound form
return render_to_response('stakeme/new_stake.html',
context_instance=RequestContext(request))
new_stake.html
<h1> New Play </h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="" method="post">
{% csrf_token %}
Stake Played: <input type="text" name="stakes" id="stakes"/><br>
Amount Won/Lost: <input type="text" name="amount_won" id="amount_won"/><br>
Date/Time of play: <input type="text" name="last_play_date" id="last_play_date"/><br><br>
<input type="submit" value="Add New Play" />
</form>
urls.py
(r'^(\d+)/new_stake/$', 'new_stake', name='new_stake' ),
forms.py
class StakeForm(forms.Form):
player_id = forms.IntegerField()
stakes = forms.CharField(max_length=200)
amount_won = forms.IntegerField()
last_play_date = forms.DateTimeField()
Any help would be appreciated. Thanks!
This answer was given to me by someone a different website. He had no desire to repost it here, but I will copy/paste in order to accept the answer and for future reference.
In the view, looking up the player_id should be called even if the POST data was not sent. That ensures you get a 404 anytime there is an invalid player_id in the URL. I simply moved that line of code above the IF statment.
Don’t define the form yourself in the template when you can. It avoids missing useful things like error messages when the form is not valid. Django provides some nifty tools to auto generate form HTML for you. I updated the form to look like the following. NOTE: I used ‘form.as_table here’, but there are some other useful methods such as ‘as_p’ if you don’t like the HTML output as a table. Here is the new new_stake.html:
Remove the player_id from your form class if its not actually part of the form (or better yet, make it a hidden field). Also, you should probably be using a ModelForm here, that will auto-populate the form elements for you for the most part after the POST data is recieved. However, I did not make that optimation here. What I did do was remove the player_id line from the form in FORMS.py since it’s already in the URL and that seems to be where you wanted to grab it from (rather than a hidden input as suggested above).
At this point, you should start seeing you’re a bit closer to getting a working form. The problem you were seeing was mainly that your form was not passing the is_valid() check, and if you look at the code, this dropped into showing you the form again. To make things seem worse, you never knew the form was invalid because you designed your own form HTML that did not include the error messages. This fix became more obvious once I used {{form}} in the template rather than using the custom form code in the original html.
A second note, you had miss-spelled the last_play_date as last_played_date. It may have worked the way you had it, but to keep a similar naming convention I renamed this to last_play_date to match the model.
Final note about views.py. You should try not to redirect to a URL defiend as a a string. URLs has a nice feature that lets you name them. You can use the reverse() function to perform a lookup as “reverse(‘stake_added’).
The final VIEWS.py looks like this:
And for good measure, here is the final URLS.py: