Django/Python: Pulling value from template into views.py - python

I currently have a search function in my views.py file like so:
def json_search(request):
query = request.GET.get('query')
api_key = locu_api
url = 'https://api.locu.com/v1_0/venue/search/?api_key=' + api_key
locality = query.replace(' ', '%20')
category =
final_url = url + "&locality=" + locality + "&category=" + category
json_obj = urllib2.urlopen(final_url)
decoded_data = json.load(json_obj)
return render(request, 'loc_search.html',
{'objects': decoded_data['objects']})
What I have set up is a drop-down search bar whereby I want the category variable within my json_search() function to automatically be assigned to the selected option on the drop-down bar before the form is submitted using the submit button. The search bar looks like this :
And the code like this:
<form action="{% url 'search' %}">
<div class="input-group">
<input name="query" input id="address" type="textbox" placeholder="City or Zipcode" class="form-control datebox">
<div class="input-group-btn">
<button class="btn btn-default" type="submit" id="addressSearch">Search</button>
<button name = "category_query" tabindex="-3" data-toggle="dropdown" class="btn btn-default dropdown-toggle" type="button">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" >
<li>Resturant</li>
<li>Activities</li>
<li>Bar / Club</li>
<li class="divider"></li>
<li>other</li>
</ul>
</div>
</div>
</form>
Is this even possible?

You would have to get the value back to the backend view code in some fashion in order for that to happen.
It would be possible to do so prior submitting the form. For example, you could use an Ajax call within the template code to hit the same URL serviced by the json_search function, passing category in the URL, and then pulling it out of request.GET.
If you wanted it to be assigned upon dropdown selection, you would want to attach a click event handler via jQuery to that dropdown, and then in that handler's function, get the selected value, and then add it to the Ajax call back to your json_search function.
In your json_search code, you'll want to differentiate handling the submit (which should be a POST) vs. general GET handling (perhaps based on whether various parameters are present in the URL).
Edit in response to comment from OP:
It's certainly not trivial, especially if you've not worked with Ajax before, but it shouldn't be too bad overall (and once you get the hang of it, this paradigm can be used for all sorts of interaction with other modules like Datatables and many others, not to mention your own Django backend).
While there are many different ways to do this, I'm a fan of using jQuery's when in conjunction with done (used in examples on the same page). The when lets you fire off multiple asynchronous Ajax requests, and the done acts as a join point where you wait for them to finish before proceeding.

Yes, this is possible, you would make all the links in the dropdown have a onclick handler which would need to save the category. Then instead of a url for the form you would use a submit function which would send your form data + the category.
That is something easy to do with angular + ui.bootstrap.
with jQuery
http://plnkr.co/edit/iBY2n9dq8Tn95IUGwNAB?p=preview
You need to transform your links not to have a valid href and instead call a function, e.g.:
Restaurant
and add a hidden field for the category
<input name="category" input="" id="category" type="hidden" placeholder="Category" class="form-control" />
and some easy javascript
function setCategory(category) {
alert('category (hidden) = ' + category);
$('#category').val(category);
}

Related

How to get the value of a variable within an html tag in flask?

I am building an app using Flask to show nearby shops, and the user can like a shop so it can be added to their liked shops list.
My question is how can i get the value inside the <h4> tag sent to Python knowing that the name attribute is a variable. The html code is below:
<form name='likeF' method='POST' action ='{{url_for("liked")}}'>
<h4 name="ShopName_{{loop.index}}">{{item.ShopName}}</h4>
<p>
Shop Description : {{item.ShopDesc}} <br>
<button type="submit" class="success button like">Like</button>
distance: {{item.ShopDistance}}
</p>
</form>
So please how am I supposed to get back the value of {{item.ShopName}}?
You can't send the text inside an <h4> tag (or any tag that is not a form input) back to the server, at least not without using Javascript. The easiest method would be to duplicate it in a hidden input element inside the form, such as:
<input type="hidden" name="ShopName" value="{{ item.ShopName }}">
Then you can access it using request.form["ShopName"].

Python Flask: Bad Request on Post method with radio-option checked

Lets say I have 2 radio buttons in my html script, of which one is checked by default:
<form action="" method="post">
<div class="radio-option checked">
<input type="radio" name="radioName" value="val_1"/>
</div>
<div class="radio-option">
<input type="radio" name="radioName" value="val_2"/>
</div>
<div>
<input type="submit" value="Confirm and continue"/>
</div>
</form>
If I click the submit button without clicking the other radio button, I get an error:
Bad Request The browser (or proxy) sent a request that this server
could not understand.
This happens because there is no value which is being transfered if a radio button is checked by default but not being selected with the mouse afterwards! This is what request.form shows me ImmutableMultiDict([]). If I select the other radio button with the mouse and click the submit button it shows me values ImmutableMultiDict(['radioName', 'val_2'])
I tried to catch the error like this, but it didn't work out:
if request.form == '':
flash('error')
return render_template('default_template.html')
How can I handle this within flask?
How can I set a default value, which can be sent to the server?
You could perform a check within flask. Check if request.form has items or if its empty and throw the error in that case.
A simple way of knowing if its empty would be, for example:
if len(request.form) == 0:
print('Error: The form is empty')
else:
print('The form has data, we can proceed')
Another way is:
if 'radioName' not in request.form:
print('Error: The form is empty')
...
But maybe flask has a better way of doing this or there are better practices to follow in these cases.
On the other hand, in the html snippet that you posted, none of the inputs is checked by default.
You have the checked css class on a div but not the checked attribute in an input with type=radio.
The correct use of checked attribute would be as follows:
<form action="" method="post">
<div class="radio-option checked">
<input type="radio" name="radioName" value="val_1" checked/>
</div>
<div class="radio-option">
<input type="radio" name="radioName" value="val_2"/>
</div>
<div>
<input type="submit" value="Confirm and continue"/>
</div>
</form>
This way, the radio input with value val_1, will be checked by default, populating the dictionary that goes to the server.
For more information, check out: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio
You can also avoid sending empty forms to the server using the required attribute to make sure that the user fills the form as expected.
To learn more about this: https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation
I hope it helps!

python flask iframe and download

I have to perform two actions based on radio button selection, either download or view a document
<form method="post" action="{{ url_for('page_after_submit') }}">
<p> Your resume </p>
<div class="radio">
<label> <input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked> Download document </label>
</div>
<div class="radio">
<label> <input type="radio" name="optionsRadios" id="optionsRadios2" value="option2"> View document </label>
</div>
<input type="submit" />
</form>
My page_after_submit has this code...
#app.route(local.URL_PREFIX + '/page_after_submit/', methods=['POST'])
def after_submit():
if 'option1' == request.form['optionsRadios']:
return/redirect ("download from this url")
if 'option2' == request.form['optionsRadios']:
return/redirect ("view in this iframe")
return (Url_for('go back to submit page if you are here')
I know my form can only have one action which is '/page_after_submit/', what code (HTML or Python in flask) I need to complete rest of my actions ??? I tried to put the iframe tags with complete download file address in the redirect for option2 but doesn't work. I also want this iframe to pop up not open a new browser window. Plus for the download, don't know what to do specially different operating system may have different path for download directory.
My goal is to not have any javascript as well, don't know if it's possible or not. Thanks in advance.
You need to craft a different response depending on how they want to see the data.
Download File
If they choose option 1, you need to set the headers and response to allow the browser to trigger a file download. Here's how you can do something like that.
View File in Iframe
If they choose option 2, you need to return an HTML response which loads the file. This can be done in an Iframe if you'd like, but it's not necessary. Here's one possible way to do that, but many others exist.

Sending data to server flask html

I am trying to create a simple checkbox that sends the data to server here is my html code.
<form action="." method="POST">
<div class="checksheet">
<input id="XML Parser" class="checkbox" type="checkbox"/>XML Parser
<input id="Feed Parser" class="checkbox" type="checkbox"/>Feed Parser
<input id="Text Parser" class="checkbox" type="checkbox"/>Text Parser
<input id="Case Normalization" class="checkbox" type="checkbox"/>Case Normalization
<input id="Stemmer" class="checkbox" type="checkbox"/> Stemmer
</div>
<div class="submit"><input type="submit" value="Send" name="raw_text"></div>
</form>
What I am trying to do is very similar to the question asked here: Send Data from a textbox into Flask?
But except with the text box.. I have checkboxes.
But I get this error:
Not Found
The requested URL was not found on the server.
If you entered the URL manually please check your spelling and try again.
MY server side code (in flask) is:
#app.route('/raw_text.html')
def home ():
file = "sample.xml"
contents = open(file).read()
contents = contents.decode('utf-8')
return render_template('raw_text.html', contents=contents,file=file)
#app.route('/raw_text.html',methods=['POST'])
def get_data():
print "REQUEST ",request.form()
data = request.form['raw_text']
print data
return "Processed"
Any suggestions.
Thanks
A few things:
Your checkbox elements need a name attribute, this is what is used when the data is sent to the back end. Each checkbox that is related to each other needs to have the same name.
Your action attribute needs to point to a URL. If you are posting it to the same page as the form, you can remove the attribute.
ID's cannot contain spaces.
To be accessible the check boxes need <label>s,

Displaying results from search API

I'm trying to get to grips with web2py/python. I want to get the user to fill in a search form, the term they search for is sent to my python script which should send the query to the blekko API and output the results to them in a new HTML page. I've implemented the following code but instead of my normal index page appearing, I'm getting the html response directly from blekko with '%(query)' /html appearing in it's search bar. Really need some help with this!
HTML form on the default/index.html page
<body>
<div id="MainArea">
<p align="center">MY SEARCH ENGINE</p>
<form name="form1" method="get" action="">
<label for="SearchBar"></label>
<div align="center">
<input name="SearchBar" type="text" id="SearchBar" value="" size = "100px"><br />
<input name="submit" type="submit" value="Search">
</div>
</form>
<p align="center"> </p>
Python code on the default.py controller
import urllib2
def index():
import urllib2
address = "http://www.blekko.com/?q='%(query)'+/html&auth=<mykey>"
query = request.vars.query
response = urllib2.urlopen(address)
html=response.read()
return html
I think you are misunderstanding how string formatting works. You need to put the address and query together still:
address = "http://www.blekko.com/?q='%(query)s'+/html&auth=<mykey>" % dict(query=request.vars.query)
Add a hidden field to your form, call it "submitted". Then reformat your controller function as such:
import urllib2
def index():
if request.vars.submitted:
address = "http://www.blekko.com/?q='%(query)'+/html&auth=<mykey>"
query = request.vars.query
response = urllib2.urlopen(address)
html=response.read()
return html
else:
return dict()
This will show your index page unless the form was submitted and the page received the "submitted" form variable.
The /html doesn't do anything. Glad your question got answered. There is python client code for the blekko search api here: https://github.com/sampsyo/python-blekko

Categories