url_for creates a url query string with & - python

Lets say i have the following script in a html template of a flask application
<script type="text/javascript">
console.log('{{ url_for('root', arg1='hello', arg2='world') }}')
<script>
and i have a flask endpoint root()
#app.route('/', methods=['GET'])
def root():
print(print(request.args))
when i call my page the internal script is rendered to
console.log('/api/art_structure?arg2=world&arg1=hello')
When I call this url my request.args dict is:
ImmutableMultiDict([('amp;arg1', 'hello'), ('arg2', 'world')])
Which is not correct since the key of arg1 is wrong.
Any clues how I can prevent jinja2 from converting & to &?

The ampersand
The correct URL is /api/art_structure?arg2=world&arg1=hello.
The problem with the above URL is that ampersand (&) cannot be written directly in HTML, because the ampersand is used for entity references. For example, to write < character in HTML, which is not a tag start, one can write <. Because of that, to write &, one should escape it, i.e. write it as &.
Jinja2 templating engine does that by default. So, you can dump the contents of any string variable even if it contains special characters and they will be correctly escaped, e.g. & will become & as in your case.
How does that work?
So, if you actually put this in your jinja template: link, it would write the following HTML code: link, and if you clicked on the link in the browser, it would correctly replace & with & and open /api/art_structure?arg2=world&arg1=hello.
(note, however, that writing plain & as it is into HTML may sometimes also work, because browsers may guess how to fix the error)
So why does it not simply work in this case?
Because you are generating JavaScript and not HTML (you are generating code within <script> and </script>. In JavaScript, & is fine and should not be escaped, so you are free to write it as it is. To tell Jinja that you do not want it to escape the string, you can use the safe filter, i.e. {{ url_for('root', arg1='hello', arg2='world') | safe}}.

Try using safe
Ex:
console.log("{{ url_for('root', arg1='hello', arg2='world') | safe}}")
MoreInfo

Related

Can i create a list column in SQLAlchemy

I want to input the content of a text area and want to output it on another page but seems like there is nothing like multiline-text area in Flask. When I do the following
content = request.form['content']
it returns a string with line breaks as '\n' but when I try to output that content with replacing \n with or
, it doesn't seem to work.
So I thought I can store the multiline content in the form of a list.
So is there db column for the list, something like
content = db.Column(db.list(String))
or is there any other alternative.
Just to clarify, to the computer these 2 text examples are exactly equivalent:
myString = """Hello
World
"""
myString = "Hello\nWorld"
We can confirm this by checking the repr value for both versions
repr(myString)
# 'Hello\nWorld'
Whether or not the formatting is performed in a "friendly way" where the newlines are rendered as such, is entirely dependent on how you choose to display them. In HTML, newlines are denoted with a <br> tag, so one option would be to store the actual HTML-formatted string in your database after inserting them. However, this may pose a security hazard by either allowing malicious links to be made clickable, or by allowing Javascript snippets to be executed when rendering the page.
The simplest solution would be to use the HTML <pre> tag, which tells it that you have already handled the formatting ahead-of-time. Using the same myString value as before, we can display it nicely with
<pre>
{{ myString }}
<pre>
using the Jinja2 syntax, as long as we pass this string to the render_template function, for example
#app.route("/")
def index():
myString = "Hello\nWorld"
return render_template("index.html", myString=myString)

How to extract a javascript object as json from a HTML page using python or nodejs?

https://yeastmine.yeastgenome.org/yeastmine/customQuery.do
The above webpage has something like this. As far as I understand, JSON does not support single quote, only double quote is allowed. So the things in {} is not a valid JSON object. What is the best way to extract this object from the resulted HTML page and convert it to JSON? Thanks.
var helpMap = {'NcRNAGene': ...
This one mentions JSON.stringify. But I am not sure how to first get helpMap as JS object in the first place in python or nodejs.
Convert JS object to JSON string
In the console of that website you can write javascript. In this case you are right that JSON.Stringify is what you want here, you use it by passing the javascript object helpMap into it as a parameter, the result is the JSON-encoded string:
jsonString = JSON.stringify(helpMap)
console.log(jsonString)
You should be able to copy that json string out of your console (in chrome there will be a "Copy" button at the end of it).
Suppose the webpage is downloaded to x.html, run the following.
grep '^ \+var helpMap' < x.html | ./main.js
main.js has the following code.
fs=require('fs');
data = fs.readFileSync(process.stdin.fd);
eval(data.toString());
console.log(helpMap);
Then use JSON.stringify() on helpMap if necesssary.

Why won't my regex parse this URL in Django?

Currently working in Django, and I'm trying to set things up so that a form on one page calls a specific URL, for which the appropriate view is rendered. I'm having trouble with the regular expression that parses the URL, as it won't read the value '\?' as an escaped question mark, which is what I believe it should be doing. The following RE checks out on Pythex.
When the app submits the form, it calls the URL:
http://127.0.0.1:8000/map/?street=62+torrey+pines+cove&city=san+diego&state=CA&radius=50&drg=4
In my project level urls.py file, I have the following:
url(r'^map/', include('healthcare_search.urls', namespace="healthcare_search")),
This calls my app level urls.py file, where I have:
url(r'^\?street=(?P<street>[a-z0-9+]+)&city=(?P<city>[a-z+]+)&state=(?P<state>[a-z]{2})&radius=(?P<radius>[0-9]{1,3})&drg=(?P<drg>[0-9]{1,3})', views.map_hospitals, name = "map_hospitals"),
This just results in a 404 error, saying the URL doesn't match any of the patterns. I know that it's a RE problem, because I removed everything from the app level RE, and submitted just http://127.0.0.1:8000/map/ to see if it would call the right view, which it did successfully. Things seem to break apart on the '\?'. Any ideas what I'm doing wrong?
As a note, this is the first time I've written a regular expression, so my apologies if it is unclear or poorly written.
You don't want to get access to the variables that way. A better option is to get them from the request, since they'll be available in the request's dictionary of variables. In your view, you can get the value of street via request.GET.get('street', None), which will return the value if street is in the request or return None otherwise.

Ajax AutoComplete Feature with Prototype and Django

I would like to integrate Django, and the JavaScript prototype library to create an autocomplete feature for a form. Can anyone recommend a prototype feature that has been tried with Django? There is this code and also this and I'm wondering if anyone would recommend one over the other for use with Django. Thanks!
I downloaded the code from this site
and followed the directions there, which was straightforward. Just include the prototype.js, scriptaculous.js, and AutoComplete.js files. Then copy paste from the directions, and change the url from assets/ac.php?m=text&s= to ?m=text&s= or even just ?s= if one query parameter is all you need.
<input type="text" id="my_ac3" name="my_ac" size="45" autocomplete="off"/>
<script type="text/javascript">
new AutoComplete('my_ac3', '?s=', { delay: 0.25, resultFormat: AutoComplete.Options.RESULT_FORMAT_TEXT });
</script>
On the server side, in your view function for that page, start the function with:
if request.is_ajax():
#match the users input here, perhaps using data from your database and/or regular expressions
text = #response text to return, in my case since I chose Options.RESULT_FORMAT_TEXT as my resultFormat, it's a string where each autocomplete item is separated by '\n'
return HttpResponse(text, mimetype='text/plain') # mimetype is text here in my case
Then place the rest of the view function under an else clause.

Creating views in django (string indentation problems)

I am new to both Python (and django) - but not to programming.
I am having no end of problems with identation in my view. I am trying to generate my html dynamically, so that means a lot of string manipulation. Obviously - I cant have my entire HTML page in one line - so what is required in order to be able to dynamically build an html string, i.e. mixing strings and other variables?
For example, using PHP, the following trivial example demonstrates generating an HTML doc containing a table
<?php
$output = '<html><head><title>Getting worked up over Python indentations</title></head><body>';
output .= '<table><tbody>'
for($i=0; $i< 10; $i++){
output .= '<tr class="'.(($i%2) ? 'even' : 'odd').'"><td>Row: '.$i;
}
$output .= '</tbody></table></body></html>'
echo $output;
I am trying to do something similar in Python (in my views.py), and I get errors like:
EOL while scanning string literal (views.py, line 21)
When I put everything in a single line, it gets rid of the error.
Could someone show how the little php script above will be written in python?, so I can use that as a template to fix my view.
[Edit]
My python code looks something like this:
def just_frigging_doit(request):
html = '<html>
<head><title>What the funk<title></head>
<body>'
# try to start builing dynamic HTML from this point onward...
# but server barfs even further up, on the html var declaration line.
[Edit2]
I have added triple quotes like suggested by Ned and S.Lott, and that works fine if I want to print out static text. If I want to create dynamic html (for example a row number), I get an exception - cannot concatenate 'str' and 'int' objects.
I am trying to generate my html dynamically, so that means a lot of string manipulation.
Don't do this.
Use Django's templates. They work really, really well. If you can't figure out how to apply them, do this. Ask a question showing what you want to do. Don't ask how to make dynamic HTML. Ask about how to create whatever page feature you're trying to create. 80% of the time, a simple {%if%} or {%for%} does everything you need. The rest of the time you need to know how filters and the built-in tags work.
Use string.Template if you must fall back to "dynamic" HTML. http://docs.python.org/library/string.html#template-strings Once you try this, you'll find Django's is better.
Do not do string manipulation to create HTML.
cannot concatenate 'str' and 'int' objects.
Correct. You cannot.
You have three choices.
Convert the int to a string. Use the str() function. This doesn't scale well. You have lots of ad-hoc conversions and stuff. Unpleasant.
Use the format() method of a string to insert values into the string. This is slightly better than complex string manipulation. After doing this for a while, you figure out why templates are a good idea.
Use a template. You can try string.Template. After a while, you figure out why Django's are a good idea.
my_template.html
<html><head><title>Getting worked up over Python indentations</title></head><body>
<table><tbody>
{%for object in objects%}
<tr class="{%cycle 'even' 'odd'%}"><td>Row: {{object}}</td></tr>
{%endfor%}
</tbody></table></body></html>
views.py
def myview( request ):
render_to_response( 'my_template.html',
{ 'objects':range(10) }
)
I think that's all you'd need for a mockup.
In Python, a string can span lines if you use triple-quoting:
"""
This is a
multiline
string
"""
You probably want to use Django templates to create your HTML. Read a Django tutorial to see how it's done.
Python is strongly typed, meaning it won't automatically convert types for you to make your expressions work out, the way PHP will. So you can't concatenate strings and numbers like this: "hello" + num.

Categories

Resources