Jinja 2 - displaying all my words instead of one - python

Please excuse my code, I am still a relative beginner trying to complete a school project! Basically, I am trying to create a language learning system where you input a word and it checks if it is correct. However, on the page learn.html all of the words in my database are coming up. I want to get it so that when you load the page there is the first word and when you click the button it checks that word, allowing the page to display the next word to translate. An example of this would be memrise, this screenshot shows the kind of system that I am trying to emulate.
I know that this is because of the for loop but I have tried lots of solutions to no success. It seems like a really easy problem but I am really stuck. I have 0 JavaScript expertise so if possible I would try to stay away from JS solutions. I will really appreciate any help possible :)
learn.html
{% block content %}
<form class = "form" id="form1" action="/learn/check" methods=["POST"]>
<td>
<h5> Please enter the spanish for : {% for word in course_content %}{{ word.english }} {% endfor %} </h5>
<input type="text" name="language_learning_input" id="desc" value="" size="100" maxlength="140"/>
<p> </p>
</td>
<input type="submit" name="button" class="btn btn-success" value="Update"/>
</form>
{% endblock content %}
snippet of main.py
#LEARN SYSTEM
#STORING DB VALUES IN LISTS
def spanish():
#setting variables
holding_spanish = []
#running db query
course_content = db.session.query(Course).all()
#iterating through db
for row in course_content:
holding_spanish.append(row.spanish)
return holding_spanish
def english():
#setting variables
holding_english = []
#running db query
course_content = db.session.query(Course).all()
#iterating through db
for row in course_content:
holding_english.append(row.english)
return holding_english
def score():
#setting variables
holding_score = []
#running db query
account_settings = db.session.query(AccountSettings).all()
#iterating through db
for row in account_settings:
holding_score.append(row.words_per_lesson)
return holding_score
#MAIN LEARN PAGE
#app.route("/learn")
def learn():
#getting values
english()
spanish()
score()
x=1
testingvalue = [score()]
acccount_settings = db.session.query(AccountSettings).all()
course_content = db.session.query(Course).all()
return render_template('learn.html', course_content=course_content, acccount_settings=acccount_settings,testingvalue=testingvalue,x=x,english=english)
#ROUTE USED TO CHECK
#app.route("/learn/check", methods =['GET'])
def learncheck():
course_content = db.session.query(Course).all()
language_learning_input = request.args.get('language_learning_input')
for row in course_content:
if language_learning_input == row.spanish:
"<h1> correcto! </h1>"
print("true")
else:
"<h1> not correcto! :</h1>"
print("false")

Basically you need to understand two things.
First, of the many words you have to return only one. *
So, how do you know which word the user has already seen?
You don't. HTTP is a stateless protocoll. That means, each request (access by a browser) is independent of another one.
But you can work around this limitation.
So, second, you need to save the state. And there are several concepts.
From the top of my head, you could use
sessions
cookies
or pass a parameter with e.h. the current word, so you can deduct the next word
That's it. Enjoy your homework and do not hesitate to create a new question when you encounter a specific problem
You could also return all words, and then do the cycling through the words via Javascript.

Related

Error in my code from transferring data from flask variable in python to html file

I am creating a flask web application which asks users to complete a quiz through a form and collect data from each session. I use a main.py file, 1 html file with the quiz, and then another one which is supposed to display dynamic results. When the submit button is clicked, it automatically directs users to the second html page with their results. It is my intention to display results based upon what options the user clicks. I attempted to accomplish this by:
Collecting data:
session["symptom1"] = form.symptom1.data
Writing this into a file
user_data.write(form.symptom1.data)
Reading file contents into a variable (3 characters into each variable)
data1 = user_data.read(3)
Assigning a Boolean value to a python variable based upon the data using a conditional:
if data1 == "op3" or data1 == "op4":
global adhd1
adhd1 = True
Rendering this to an html file:
return render_template("takethequiz.html", form = form,adhd1=adhd1,adhd2=adhd2,adhd3=adhd3,adhd4=adhd4)
Creating a conditional in a second html file (treatmentplan.html)=
{% if adhd1 == True %}
Use productivity apps to increase your focus
{% else %}
Great job! You are skilled at staying on task!
{% endif %}
However this does not do anything. Meaning, no matter what I click, the treatment plan is always set to adhd1 = False. How do I combat this?
Code Screenshots on Google Doc: https://docs.google.com/document/d/1uF1Q-zfKNx-d5jzbaIK_BKGbLRm0tCGgaz92-V2hDjE/edit?usp=sharing
Thank you!

Is there a function that updates var value in django views.py?

Good day, I am very new to django and programming in general. Is there a function that updates variable values based on user input?
I would like to write a function that displays output to html using HttpResponse and waits for user input...
on my views.py, I have the following:
def getResponse(request):
userMessage = request.GET.get('userMessage');
return HttpResponse("Good to see you. May I know your name?")
name=input(userMessage)
return HttpResponse("Good to know you", name,". I can tell you your age if you tell me which year you were born")
year=input(userMessage)
age = ((datetime.date.today().year) - year)
return HttpResponse("You are", age "old")
My Html is looking like this:
<div id="userInput">
<form id="user_Input" method="post">
{% csrf_token %}
<input type="text" name="userMessage" id="textInput" placeholder="Type your
message...">
<input type="submit" id="buttonInput" name="" value="Send">
</form>
</div>
</div>
<script type="text/javascript">
function getUserResponse(){
var userText =$('#textInput').val();
var userHTML = "<p class='userText'>User: <span>"+userText+"</span></p>";
$('#textInput').val("");
$('#pal').append(userHTML);
$.get('/qpal/getResponse',{userMessage:userText}).done(function(data){
var returnedMessage = "<p class='botText'> Pal: <span>"+ data +"</span></p>";
$('#pal').append(returnedMessage);
})
}
$('#buttonInput').click(function(e){
e.preventDefault();
getUserResponse();
})
</script>
The html works, however it is only displaying the first HttpResponse value everytime like shown in the picturescreenshot.
In pure python environment the code will work perfectly using only print and input and I am trying to make it work the same on the web (html) using django
Thanks in advance for your time
First of all you are using too many return without condition which is wrong and due this your function always return the first message.
you should store or update the message variable based on the user input such as you can use another variable on your HTML named as Qnum question number and based on that show next next message:-
def getResponse(request, QNum):
message = "Hi"
if QNum == 1:
userMessage = request.GET.get('userMessage');
message = "Good to see you. May I know your name?"
elif QNum == 2:
message = "Good to know you, {}. I can tell you your age if you tell me which year you were born".format(input(userMessage))
elif QNum == 3:
year=input(userMessage)
age = ((datetime.date.today().year) - year)
message = "You are, {} old".format(age)
return HttpResponse(message)

Flask correct variable value on terminal but not in HTML template

Similar question which does not solve my problem.
I have a Flask app which reads from a database and renders an HTML template using the DB data. I'm trying to manipulate a value I get from the DB before sending it to the HTML template and this doesn't work.
Python code:
#app.route('/pilot', methods=['GET'])
def form_view():
result = {}
# query DB and get cursor
numQuestions = 0
for row in cursor:
row.pop('_id', None) # delete the key and add modified key back
row['_id'] = row['stage'][-1] # get only last char- eg, "1" from "stage1", "2" from "stage2" and so on
print(row['_id'])
result[numQuestions] = row
numQuestions += 1
return render_template("form.html", count=numQuestions, result=result, debug=app.debug)
Output when run on terminal is as expected:
1
1
1
2
2
2
Jinja2 fragment of form.html:
{% for row in result[row_num]['scrutiny_stage'] %}
{{ row['_id'] }}
{% endfor %}
Output on browser:
stage1 stage1 stage1 stage2 stage2 stage2 stage2
Can anyone help me understand what I'm doing wrong here and how I can get the correct value of the variable I'm setting in the Python code to show up in the HTML template being rendered by Flask?
Thanks.
Thanks for the tips folks, even though I couldn't share all the context (since I have to protect proprietary info), they were helpful. I managed to solve this with multiple steps:
I redid my DB schema so that every document has an '_id' key with a plain numeric value. I dropped the 'stage': 'stage1' kinds of fields. The 'stage' is now computed dynamically in the code base on the DB query results.
Then I changed the Flask view function to add a 'stage' key to the result dict being passed to the HTML template (no mucking around with the '_id' field):
numQuestions = 0
for row in cursor:
for line in row['scrutiny_stage']:
row['stage'] = line['_id']
result[numQuestions] = row
numQuestions += 1
Finally, in my Jinja2 block, I realized that I need to operate over the result as a dict, so I changed it to use the dict.values() method:
{% for row in result.values() %}
{{ row['stage'] }}
{% endfor %}
Now, I get the same values printed in the terminal as well as in my browser.

How to Take Checkboxes in Python

I am trying to use checkboxes in my HTML, return these checkboxes to my python backend, and then increment three counters if the box is clicked.
Right now my HTML is as follows and works fine:
<form method="post">
<input type="checkbox inline" name="adjective" value="entertaining">Entertaining
<input type="checkbox inline" name="adjective" value="informative">Informative
<input type="checkbox inline" name="adjective" value="exceptional">Exceptional
</form>
and then on my python backend I have the following:
def post(self):
adjective = self.request.get('adjective ')
if adjective :
#somehow tell if the entertaining box was checked
#increment entertaining counter
#do the same for the others
When your form has multiple checkboxes with the same name attribute, the request will have multiple values for that name when the form is submitted.
Your current code uses Request.get to get a value, but this will only retrieve the first value if there is more than one. Instead, you can get all the values using Request.get_all(name) (in webapp) or Request.get(name, allow_multiple=True) (in webapp2). This will return a (possibly empty) list with all the values for that name.
Here's how you could use in in your code:
def post(self):
adjectives = self.request.get('adjective', allow_multiple=True)
for a in adjectives:
# increment count
self.adjective_count[a] += 1 # or whatever
# do more stuff with adjective a, if you want
# do other stuff with the request
wouldnt it be easier to change the name="" and put it the same as the value, so you can jsut ask
IF entertaining :
IF informative :
im no python programmer just tell let you no

A python coded "alert"-like dialog or template

update 0:
There is a subtle, but serious, error in my code and in my explanation below because I cannot only compare the name on the template with the hiddenname on the template (that much only tells me that the user has made a change like a checkbox change would tell me, but purposely there are no checkboxes), I also need to compare name to the status of name in the datastore of reservations to see if someone else has already reserved the time slot. So I cannot use javascript and I have to rewrite some of the code below to make the correct comparison, too. And may original question remains as suggested by the Title of this question. (In one of the comments I erroneously said that javascript would work.)
update 0:
I am trying to write a sort of "alert" in the way that this code suggests where I use the Trans model and the gae datastore (further below) to communicate between my main app and the "alert template". I have a few problems.
Initially I had my need for this alert in an another part of my code in an else: clause, not in an elif: clause. When I tried to use the simpler version of my alert in the elif code, python seemed to ignore the self.response.out.write(template.render(path, template_values)) and just went on to this code which ended my conditionals: return webapp2.redirect("/read/%s" % location_id). So, as you can see in my code I have commented out the ignored former code line and attempted to replace it with something more like the latter code line, but with that latter line directed to unexpected instead of read. You can see from my code it is still a mix between the two approaches and I could use help sorting that out. Is there really something different about else: and elif: regarding this?
Originally I had not anticipated my desire to call the same html template and Trans model from so many places in my code, so I did not design a key or ID or key_name into the design of using Trans. And now I am having trouble implementing a version with such detail.
I have been looking for an example of how such "alert templates" can be made in python. They are so easy in javascript, but I am trying to do the user input validation in my python code. Any pointers to examples or docs would be greatly appreciated.
weekday_key = db.Key.from_path('Locations',location_id,'Courts', court_id,'Days',weekday)
if name == hiddenname:
pass
elif name != hiddenname and hiddenname == "":
reservation = Reservations.get_or_insert(time[2],parent=weekday_key)
reservation.hour = time[0]
reservation.minute = time[1]
reservation.year = int(year)
reservation.nowmonth = int(nowmonth)
reservation.day = int(day)
reservation.nowweekday = int(nowweekday)
reservation.name = name
reservation.put()
elif name != hiddenname and name!="":
reservation = Reservations.get_by_key_name(time[2],parent=weekday_key)
reservation.hour = time[0]
reservation.minute = time[1]
reservation.year = int(year)
reservation.nowmonth = int(nowmonth)
reservation.day = int(day)
reservation.nowweekday = int(nowweekday)
reservation.name = name
reservation.put()
reason='This was in that time slot already: '
trans = Trans(parent=reservation.key().name()) #this line is iffy
trans.reason=reason
trans.name=hiddenname
trans.put()
iden = trans.key().id() # this is part of the iffy just above
template_values = {'trans':trans}
path = os.path.join(TEMPLATE_DIR, 'unexpected.html')
#self.response.out.write(template.render(path, template_values))
return webapp2.redirect("/unexpected/%s/%d" % (time[2],iden) #more iffy
else:
pass
My model for Trans in next.
class Trans(db.Model):
reason = db.StringProperty()
name = db.StringProperty()
My jinja2 equipped unexpected.html template is as follows.
{% extends "base.html" %}
{% block content %}
This unexpected result occurred. {{ trans.reason }}:<emph style="font-weight: bold">{{ trans.name }}</emph>
<br /><br />
<div id="inputdata">
<label>Click the "Ok" button to go back to the previous page so you can elect to edit your entry, or not.
</label>
<button onclick="window.history.back()">Ok</button>
</div>
{% endblock content %}
This question is answered here. It could have been answered in this question, but apparently there was too much information given and no one saw the answer.

Categories

Resources