I'm trying to create my first django app - sports predictions game.
I want user to select from three possible results using 3 buttons (images) which pass 3 different values to the db:
1 - home team wins
0 - draw
2 - away team wins
I am able to save data using forms when I type something into it, but how do I pass value of these buttons to my database?
code on my game.html:
{% csrf_token %}
{{ form }}
<input type="submit" value = 1>
<input type="submit" value = 0>
<input type="submit" value = 2> </form>
and my view:
def game(request, Game_id):
thisgame = get_object_or_404(Game, pk=Game_id)
nextgame = int(thisgame.id)+1
template = loader.get_template('polls/game.html')
form = NewBetForm(request.POST or None)
current_user = request.user
allgames = Game.objects.all()
betchoices = BetChoice.objects.all()
context = { 'thisgame': thisgame,
'nextgame': nextgame,
'form': form,
'current_user': current_user,
'betchoices': betchoices,}
if form.is_valid():
bet = form.save(commit=False)
bet.gameid = Game.objects.get(id=Game_id)
bet.userid_id = current_user.id
bet.save()
else:
print (form.errors)
and my form:
class NewBetForm(forms.ModelForm):
class Meta:
model = GameBet
fields = ['bet']
and the error I get is Bet - this field is required
Thank you for all ideas!
you can set name for it like :
<input type="submit" name="send1" value ="1">
Note : you should value part like value ="1"
and in views.py:
if request.method == 'POST':
if request.POST["send1"] == "1":
//do some thing
elif request.POST["send1"] == "2":
//do domthing
else://request.POST["send1"] == "3"
//do something
i hope it will help you :)
As with any other type of form field, a submit button needs a name attribute before it will send any data to the backend. From there, you can just pick up its value via request.POST['whatever_the_name_is'] and assign it to your newly created object - or, if you use the name that is already a field in the form, it will be assigned automatically.
Related
Good day.
The challenge is:
Create a form that will change the parameters of the model fields, based on user input.
My logic is this. I tried to create a form for entering changes:
In the lists , I recorded all the ID and field names of the model;
class RefDataForm(forms.Form):
NODE_ID_LIST=[('YE102_4G','YE102_4G'),('AG001_4G','AG001_4G')]
ANRFUNC_PARAM_LIST=[('zzztemporary7','zzztemporary7'),('zzztemporary2','zzztemporary2')]
change_id = forms.CharField(label='Node ID for Change', widget=forms.Select(choices=NODE_ID_LIST))
change_param_name = forms.CharField(label='Parameter name for Change', widget=forms.Select(choices=ANRFUNC_PARAM_LIST))
value = forms.CharField(label='Value')
Next in view.py, I'm trying to create a .update command that should accept changes.
def ref_test(request, template_name ='ref_test.html'):
if request.method == 'POST':
test=RefDataForm(request.POST)
if test.is_valid():
change_id = request.POST['change_id']
change_param_name = request.POST['change_param_name']
change_value = request.POST['value']
update_form = Ran4GRfAnrfunction.objects.filter(pk__in=change_id).update(change_param_name=change_value)
else:
test=RefDataForm()
return render(request, template_name, {'test':test})
My html is :
<form method="post">
{% csrf_token %}
{{ test.change_id }}
{{ test.change_param_name }}
{{ test.value }}
<button type="submit">Search</button>
</form>
However, I get an error
*Ran4GRfAnrfunction has no field named 'change_param_name' *
How do I pass field_name through a form?
In manage.py shell, I tried to do it - and its work.
from dumper.models import *
change_id = ['AG001_4G', 'AG002_4G']
change_value = ('Okay')
change_param_name = ('zzztemporary2')
Ran4GRfAnrfunction.objects.filter (pk__in = change_id) .update (zzztemporary2 = change_value)
How do I pass the value of change_param_name to .update ?
Maybe you've already figured this out since the questions been here for five hours at this point.
I can't exactly test this, but it looks like your problem is right here. This line is telling it to change the change_param_name field - not to change the field matching the name stored in change_param_name.
.update(change_param_name=change_value)
You should be able to fix this by putting the values into a dictionary and unpacking it.
.update(**{change_param_name: change_value})
I'm working on my first django project which is a sport betting app. My models are:
class Game(models.Model):
home_team = models.CharField(max_length=100)
away_team = models.CharField(max_length=100)
class GameBet(models.Model):
gameid = models.ForeignKey(Game)
bet = models.IntegerField(default=None) #values: 1(home win), 0 (draw), 2 (away win)
userid = models.ForeignKey(User)
I am able to save user bets using a single game view, when I pass gameid in url, but that is not very effective.
I created a simple page with list of games with 1 form per game for a start (at the end I would prefer to send all bets with one button):
{% for game in games %}
{{ game.id }} | {{ game.home_team }} | {{ game.away_team }} | <form method="post"> {% csrf_token %} {{ form }} <input type="submit" value="bet" /> </form> <br> {% endfor %}
and my form is:
if request.method == 'POST':
#if request.POST["bet"] == 'bet':
form = NewBetForm(request.POST)
if form.is_valid():
bet = form.save(commit=False)
bet.gameid = [r.id for r in owing_games] #it gives me a list and ValueError Cannot assign "[10, 11, 12]": "GameBet.gameid" must be a "Game" instance.
bet.userid_id = current_user.id
bet.bet = form.value()
bet.save()
How can I pass a single game.id in that case?
EDIT:
I think I can use request.POST.get(something) but I don't know how to pass my {{ game.id }} from template to views
Create a hidden input field with value as game.id.
Example:
<input type='hidden' value='{{ game.id }}' name='game_id'>
Place the above html code within the form block. Now, you can access the value in the view as request.POST['game_id'].
And, if you want to place same bet for multiple game ids, then loop over game ids, retrieve the Game instance from database and assign each new GameBet instance gameid as the retrieved Game instance.
Single Game ID Example:
game_id = request.POST['game_id']
if request.method == 'POST':
# rest of the code
if form.is_valid():
bet.game_id = Game.objects.get(id=game_id)
Multiple Game IDs Example:
game_ids = request.POST['game_ids']
if request.method == 'POST':
for game_id in game_ids:
bet = form.save(commit=False)
bet.game_id = Game.objects.get(id=game_id)
bet.save()
# return response after loop
Database:
database
Model :
class Donor(models.Model):
firstName = models.CharField(max_length=50)
lastName = models.CharField(max_length=50)
bloodType = models.CharField(max_length=10)
createdDate = models.DateTimeField(auto_now_add=True)
lastAttendance = models.DateTimeField(auto_now_add=True)
View:
donor_id = None
if request.method == "GET":
donor_id = request.GET['id']
if donor_id:
donor = Donor.objects.get(id=int(donor_id))
if donor:
donor.createdDate = True
donor.save()
Error message: MultiValueDictKeyError at /donors/
"'id'"
Problem:
approach
Click the attentd button, take user's id and save in the database current date.
Any solutions appreciated!!
You need to add value in button so you can get value as GET parameter.
<form action="get">
<button
type="submit"
class="btn attendBtn"
value="{{ item.id }}"
name="attend">attend
</button>
</form>
Normally in input buttons we don't specify value attribute, It's because user entered value and submit the button for processing. But in your case we need to declare explicitly value.
Try
if request.method == "GET":
donor_id = request.GET.get('id')
request.GET['key'] would raise a KeyError if the key doesn't exist.
request.GET.get('key', '') allows us to specify a default value, if the key is not available. If omitted, the default value is ''. So, it won't raise error, if there is no id in the request.GET
Use the MultiValueDict's get method. This is also present on standard dicts and is a way to fetch a value while providing a default if it does not exist.
donor_id = request.GET.get('id', False)
Generally,
my_var = dict.get(<key>, <default>)
New to Django and having problem seeing form fields displayed. What I see is just the submit button. If pressed, the form is finally presented, but with the format for a form that had bad data (typical 'this field is required' error for each box, red box, etc).
The form works fine after entering data and again pressing submit (stores entries in my db). I have a number of forms on the same page that have the same behavior.
Example of one form:
#model
class dbPara(models.Model): #parameters
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
username = models.CharField(max_length=10)
turns = models.FloatField(default=27)
units = models.FloatField(default=5)
rise = models.FloatField(default=2.9)
rescutL = models.FloatField(default=0.0833333333)
rescutH = models.FloatField(default=0.333333333)
LorR = models.CharField(max_length=1, default='R')
def __str__(self):
return self.timestamp, self.username, self.turns, self.units, self.rise, self.rescutL, self.rescutH, self.LorR
#form
class ParaForm(ModelForm):
class Meta:
model = dbPara
widgets = {'username': forms.HiddenInput()}
fields =['username', 'turns', 'units', 'rise', 'rescutL', 'rescutH', 'LorR']
#view
def importParameters(request):
if request.method == 'GET':
form = ParaForm()
else:
form = ParaForm(request.POST)
if form.is_valid():
entry=dbPara(username = request.POST.get('username'),
turns = request.POST.get('turns'),
units = request.POST.get('units'),
rise = request.POST.get('rise'),
rescutL = request.POST.get('rescutL'),
rescutH = request.POST.get('rescutH'),
LorR = request.POST.get('LorR')
)
entry.save()
return render(request, 'main.html',
{'ParaHTML' : form })
#url
urlpatterns = patterns('Inputs.views',
url(r'^importParameters/$', 'importParameters', name='urlParameters'),
)
#main.html
<div class='col-lg-3'>
<h4>Set Rosetta Parameters</h4>
<action="{% url "urlParameters" %}" method="post">{% csrf_token %}
{{ ParaHTML|crispy }}
<input type="hidden" name = "username" value = "{{ user.get_username }}">
<input type="submit" class="btn btn-primary" value="Set">
</form>
</div>
Appreciate any advice (better simple than 'most correct but complicated')
Could it be due to using default in the model? Would that not 'fill in the form' and result in 'POST' at the initial visit to the page, resulting in just the button? Thoughts?
One Suggesestion here ....
if Using request.POST.get('anything') simply then it Will raise error if particular string not find as in example('anything') string...
Because request.POST.get('anything') will return None if 'anything' is not in request.POST.
Additionally, .get allows you to provide an additional parameter of a default value which is returned if the key is not in the dictionary.
e.g: Corrected will be request.POST.get('anything', 'mydefaultvalue')
I'm trying to let the user select one 'thing' from a list (from the database), then go find other stuff in the database using that record. But I cannot get the selection info from the selection page.
I'll try to make this a pretty complete snapshot of the relevant code, but I may remove too much or leave too much in, sorry.
my models.py:
urlpatterns = patterns('',
url(r'^$', 'dblook.views.index', name='home'),
url(r'^dblook3/', 'dblook.views.try3', name='home2'),
url(r'^dblook4/', 'dblook.views.try4', name='home3'),
)
my dblook/models.py:
from django.db import models
class serial_number(models.Model):
def __unicode__(self):
return self.serialno
#return self.question
class Meta:
managed=False
db_table='serial_number'
sn_id = models.AutoField(primary_key=True)
serialno = models.CharField(max_length=128)
comment = models.ForeignKey(comment,null=True,db_column='comment')
my views.py (I will skip all the imports other than the database model import. If anyone really wants them I'll update with them)
from dblook.models import *
class SerialnoSelectForm(forms.Form):
serialno = forms.CharField(max_length=16)
selected = forms.BooleanField()
class serialform(ModelForm):
class Meta:
model = serial_number
exclude=('comment','sn_id')
selected = forms.BooleanField()
class snselect(forms.Form):
sno = forms.ChoiceField()
def try3(request):
if ( request.POST ):
output = "HEllo world, thanks for posting"
return HttpResponse(output)
else:
sslst = snselect(serial_number.objects.filter(serialno__startswith="A128").order_by('-serialno'))
t = loader.get_template('select_serialno.html')
c = Context({
'sslst': sslst,
})
c.update(csrf(request))
return HttpResponse(t.render(c))
def try4(request,dsn):
if ( request.POST ):
output = "HEllo world, thanks for posting to 4"
return HttpResponse(output)
else:
return HttpResponse("Error")
And my template (select_serialno.html) is:
<h1>Select a serial number</h1>
<ul>
<form method='post' action'='/dbtest4/{{serial_number.sn_id}}/showme'>
{% csrf_token %}
{% for sn in sslst %}
<input type="submit" name="sn.serialno" id="choice{{ forloop.counter }}" value="{{choice.id}}"/>
<label for="choice{{ forloop.counter }}">{{ sn.serialno }}</label><br/>
{% endfor %}
<input type="submit" value="data" />
</form>
When I go to dblook3, I get a nice list from the database of serial numbers, along with a button that, if I hit goes immediately to the dblook4 URL (in this case, its ALWAYS '/dbtest4//showme/' instead of something like '/dbtest4/3/showme/). Unfortunately, I cannot seem to have any way to tell what button they hit.
No matter WHAT I put in for the 'stuff' in <form method='post' action'='/dbtest/{{stuff}}/showme'>, it is always empty.
I also tried things like if( 'choice' in request.POST ): in try4 in veiws.py, but that didn't work either.
So, how do I get ANY information about what was selected from 'look3' over to 'look4'? I'll take just about anything... However, if you can explain why I'm doing that hopefully your answer will not only solve my problem, but help others understand...
(if the above looks pretty 'evolutionary' that's because I've been hacking on this for 3 days now...)
Thanks!
You need to POST the information to the look4 dblook form:
<form method='post' action'='{% url dblook.views.try4 %}'>
At the moment you have /dbtest/{{serial_number.sn_id}}/showme which doesn't make any sense. You don't have a serial_number variable in your context so I don't know where that comes from. You have def try4(request,dsn): as your view definition which suggests that you are trying to load information on the try4 view depending on what was selected fromt he try3 view (although I am guessing this as you haven't explained what you are trying to do). If that is the case, you need to do that based on the data passed via POST instead of url parameters. Something very vaguely like the following:
def try4(request):
if request.method == "POST":
form = snselect(request.POST)
if form.is_valid():
data = form.cleaned_data
# Get the selected item from your choice field and retrieve the
# corresonding model object with that id
...