I register URL with callback function like this url(r'^G2S/TestList$', testList)
and this is callback function
def testList(request):
fi = open('testlist.html', 'r')
html = fi.read()
fi.close();
#html = '<html><body> <FORM ACTION="/G2S/HostReceiver" METHOD="POST"> First name: <INPUT TYPE="TEXT" NAME="firstName" VALUE="J. Random"><BR> Last name: <INPUT TYPE="TEXT" NAME="lastName" VALUE="Hacker"><P> <INPUT TYPE="SUBMIT"></FORM> </body></html>'
return HttpResponse(html)
the problem i have suffered is when calling open('testlist.html', 'r') in the callback function(if i use eclipse dejango run)
django is saying Exception Value : [Errno 2] No such file or directory: 'testlist.html'
but on the contrary, if i use command line with python manage.py runserver
it work normally with no the error.
the project hierarchy is like below
project folder
|
src folder
|
manage.py
testlist.html
why it only makes the error with eclipse
and one more thing, why does eclipse break point on debug mode seem not working?
for example i check a break point at the callback function above(testList), and enter to
http://127.0.0.1:8000/G2S/TestList on debug mode, i think eclipse should stop at the point i check, though error occur, but does't, why?
Read about how to use templates in your projects. Using file operations like that is not recommended.
Add this to your settings.py file
TEMPLATE_DIRS = (
os.path.join(PROJECT_ROOT, '<app>/templates'))
Then add your html files to the project/<app>/templates folder.
Then render the templates in your view using
return render(request, 'testlist.html')
Related
I am using python-docx to save a word file and I have set a specific path but since path aren't the same for every user I would like to have a dialogue when the user clicks on download so he can choose exactly in which local repository to save the file.
What I have now:
#app.route('/download_file')
def save_doc():
filename = 'test.docx'
filepath = os.path.join(r'C:\Users\Joe\Desktop', filename)
document.save(filepath)
return 'meh'
Implementing the logic you described requires work on the front-end. Let's simplify the problem by assuming that the user manually types in the download target directory. (In practice, it would make more sense for there to be a pop-up window allowing the user to browse the directory on a file explorer.)
<form action="/download" method="post">
<input type="text" value="" name="dir">
<input type="submit" value="Download">
</form>
Then, in Flask, you might specify the following:
from flask import Flask, request
#app.route('/download', methods=['GET', 'POST'])
def save_doc():
if request.method=='POST':
download_dir = request.form['dir'] # Access user input from backend
filename = 'test.docx'
filepath = os.path.join(download_dir, filename)
document.save(filepath)
return 'Download complete'
else:
pass # Whatever implementation you want for 'GET' method
This is incomplete code that I wrote without knowledge of the structure of your project, and so may not work if it is simply copied and pasted into your source code. The implementation is also quite basic, so consider it a baseline model to help you get started on baking the user interactive dialogue system.
I'd be happy to answer any questions you might have.
I have received a compressed Odoo instance as a ZIP file. My purpose was to unzip it and make it work in my computer. I was able to do it with no problem.
Now, I have to make that instance work in another server, so I have moved the instance from my computer to the mentioned server.
The only difference (apparently) between both installations is that in the new server I am using virtualenv to install all the Python3 packages and to run Odoo. In this new server, when I start Odoo, I see the message:
The database manager has been disabled by the administrator
And I have no chance to create a new database from the interface.
The same instance of Odoo, in my computer, shows the database manager to create a new database, as always.
Any ideas? Could be the virtualenv the problem?
When I searched Using IDE for this sentence I found it in this file \web\views\database_manager.html There is a condition to show this sentence it's:
{% if not list_db %}
<div class="alert alert-danger text-center">
The database manager has been disabled by the administrator
</div>
It's shown when this list_db variable have falsy value. now this variable is passed to this template (html page) by this method:
def _render_template(self, **d):
d.setdefault('manage',True)
d['insecure'] = odoo.tools.config.verify_admin_password('admin')
d['list_db'] = odoo.tools.config['list_db']
.....
.....
return env.get_template("database_manager.html").render(d)
This means that this value is retrieved from configuration file, So make sure that this value is set to True in the configuration file:
[options]
addons_path = .....
admin_passwd = ....
....
....
list_db = True
Didn't know about this option until know, Very good question as always #forvas.
I have tried to get the autoprefixer filter to work with flask_assets by following the instructions in the Flask_Assets documentation, but it does not appear to apply the filter. Here is my code:
# construct flask app object
from flask import Flask, render_template_string
flask_args = { 'import_name': __name__ }
flask_app = Flask(**flask_args)
from flask_assets import Environment, Bundle
assets = Environment(flask_app)
assets.config['AUTOPREFIXER_BIN'] = 'postcss'
assets.config['AUTOPREFIXER_BROWSERS'] = [ '> 1%' ]
css_min = Bundle('../styles/mycss.css', filters='autoprefixer', output='styles/test.css')
assets.register('css_assets', css_min)
#flask_app.route('/')
def landing_page():
html = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\
<head>{% assets "css_assets" %}\
<link rel="stylesheet" href="{{ ASSET_URL }}" type="text/css">\
{% endassets %}\
<title>Hello</title>\
</head>\
<h1>Hello World</h1>\
<p>Just a test of flask</p>'
return render_template_string(html), 200
if __name__ == '__main__':
flask_app.run(host='0.0.0.0', port=5000)
I have been able to apply the cssmin, pyscss, uglifyjs and jsmin filters successfully. I can also run autoprefixer on the command line to successfully compile a transformed output:
postcss --use autoprefixer --autoprefixer.browsers "> 1%" -o test.css mycss.css
However, when trying to run autoprefixer through flask_assets registration, the process neither throws an error nor does it seem to take the required time to compile. It does produce the output file but when I examine the resulting file, none of the prefixes have been applied.
UPDATE: This problem seems to occur whenever attempting to configure options for ANY filter. I have not been able to get uglifyjs to accept 'UGLIFYJS_EXTRA_ARGS' or for the pyscss filter to adopt a new style using 'PYSCSS_STYLE' either. I have tried to set these configuration as environmental variables using os.environ['AUTOPREFIXER_BIN'] as well as attempting to pass them through flask.config['AUTOPREFIXER_BIN']. But none of the configuration settings have been applied when the filter is run. It is also not clear to me where in the code itself the configuration options are constructed by either Bundle or Environment.
One SO post claims to have found a way to get a configuration setting to work, but the post does not show the entire workflow of how flask_assets needs to be setup to ingest these options.
Perhaps someone can help me understand what I am doing wrong?
Autoprefixer:
There is nothing wrong with your code1. You are just not using the correct filter for the latest version of Autoprefixer. If you look at the history of the releases in that link, since version 6.0.0, it started using postcss. Your code will work for versions older than 6.0.0.
Webassets has provided support for versions after 6.0.0 (inclusive), by providing the autoprefixer6 filter.
Therefore all you have to do is change the filter(s) while initializing your bundle, like so:
css_min = Bundle('../styles/mycss.css', filters='autoprefixer6', output='styles/test.css')
Other Filters' Configurations:
Don't use os.environ, that is not the way to set configuration variables for Flask and flask-extensions. The most common (and preferred) way to set configuration for extensions is by using the flask Config itself, and in large projects this is done using a separate config file. The extensions will pickup its configuration options from flask's config.
Depending on which extension you use, you can also set the config separately like you have done, but that is rarely used, from what I have seen so far.
Please check the Flask's Configuration related documentation for some good examples on how to setup configuration for your app "properly".
from flask import Flask, render_template_string
from flask_assets import Environment, Bundle
# construct flask app object
flask_args = {'import_name': __name__}
flask_app = Flask(**flask_args)
assets = Environment(flask_app)
# specify the bin path (optional), required only if not globally installed
assets.config['AUTOPREFIXER_BIN'] = 'path/to/postcss'
assets.config['AUTOPREFIXER_BROWSERS'] = ['> 1%', ]
# use the autoprefixer6 updated filter
css_min = Bundle('../styles/mycss.css', filters='autoprefixer6',
output='styles/test.css')
assets.register('css_assets', css_min)
#flask_app.route('/')
def landing_page():
html = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\
<head>{% assets "css_assets" %}\
<link rel="stylesheet" href="{{ ASSET_URL }}" type="text/css">\
{% endassets %}\
<title>Hello</title>\
</head>\
<h1>Hello World</h1>\
<p>Just a test of flask</p>'
return render_template_string(html), 200
if __name__ == '__main__':
flask_app.run(host='0.0.0.0', port=5000)
Remember to clean out the previously generated files, if the source css/js has not changed, i.e remove the output files, and the .webassets-cache folder.
1Except for code style & formatting conventions!
So, I'm trying to learn TDD for Flask, by translating this code to Flask. I've been trying to find how to render a template to a string for a while now. Here is what I have tried:
render_template(...)
render_template_string(...)
make_response(render_template(...)).data
and none of them seem to work.
The error in each case seems to be
"...templating.py", line 126, in render_template
ctx.app.update_template_context(context)
AttributeError: 'NoneType' object has no attribute 'app'
in templating.py's render_template function.
My test code is as follows:
def test_home_page_can_save_POST_request(self):
with lists.app.test_client() as c:
c.get('/')
rv = c.post('/', data = {'item_text':"A new list item"})
# This test works
self.assertIn("A new list item", rv.data)
# This test doesn't
self.assertEqual(rv.data,flask.make_response(flask.render_template('home.html',new_item_text='A new list item')).data)
with home.html as follows:
<html>
<body>
<h1>Your To-Do list</h1>
<form method="POST">
<input name="item_text" id="id_new_item" placeholder="Enter a to-do item" />
</form>
<table id="id_list_table">
<tr><td>{{ new_item_text }}</td></tr>
</table>
</body>
</html>
Edit: I've added more files, because the error may be unrelated to the actual function used. I'm using exactly what Celeo has suggested in his answer.
Celeo is correct, but there are two additional things to consider (one of which is peculiar to the render_template function):
First, it looks like you have an indentation problem in your revised function. It looks like you're calling rv.data outside of the "with" statement. The "assertEqual" statement should be within the same block/indentation-level as the "assertIn" statement. (It looks like you've placed it outside of the block at the moment.)
Second -- and more importantly -- the render_template function in flask adds newline characters at the beginning and end of the outputted HTML. (You can verify this from the python interactive shell by printing the following command to stdout:
flask.render_template('home.html',new_item_text='A new list item').data # adds '\n' at start & end
The output you'll get will have newline characters ("\n") at the beginning and end of the output.
Therefore, you should try stripping the output with the strip() function as shown below:
def test_home_page_can_save_POST_request(self):
with lists.app.test_client() as c:
c.get('/')
rv = c.post('/', data = {'item_text':"A new list item"})
self.assertIn("A new list item", rv.data)
# Suggested Revision
self.assertEqual(rv.data,flask.make_response(flask.render_template('home.html',new_item_text='A new list item')).data.strip())
That should hopefully do the trick.
You're on the right path with make_response:
response = make_response(render_template_string('<h2>{{ message }}</h2>', message='hello world'))
Then,
response.data
is
<h2>hello world</h2>
That response object is documented here.
I am going through a short Python tutorial, but I can't get the last exercise to work.
This is the source code of app.py
import web
urls = (
'/', 'Index'
)
app = web.application(urls, globals())
render = web.template.render('templates/')
class Index(object):
def GET(self):
greeting = "Hello World"
return render.index(greeting = greeting)
if __name__ == "__main__":
app.run()
and this is the view, index.html
$def with (greeting)
<html>
<head>
<title>Gothons of Planet Percal #25</title>
</head>
<body>
$if greeting:
I just wanted to say <em style="color: green; font-size: 2em;">
greeting</em>.
$else:
<em>Hello</em>, world!
</body>
</html>
The file app.py is under this directory: C:\Users\Lucas\Desktop\Learn Python The Hard Way\ex50\gothonweb\bin
and index.html is at: C:\Users\Lucas\Desktop\Learn Python The Hard Way\ex50\gothonweb\templates
So, when I want to run the sample code, I type this in the command prompt:
C:\Python26\python.exe "C:\Users\Lucas\Desktop\Learn Python The Hard Way\ex50\gothonweb\bin\app.py"
After that, "http://0.0.0:8080" is displayed on the console, so I go to http://localhost:8080/ in my browser
but I get back a long traceback starting with
<type 'exceptions.AttributeError'> at /
No template named index
Python C:\Python26\lib\site-packages\web\template.py in _load_template, line 992
Web GET http://localhost:8080/
What is going on and how do I fix it?
Thanks in advance!
I had this problem as well but running on OSX. Ultimately Zed Shaw saw my pleas for help and saw the mistake I was making.
I was running
~/projects/gothonweb/bin $ python app.py
Zed reminded me that I needed to be running this:
~/projects/gothonweb $ python bin/app.py
to allow the templates folder to be found. After I did that it worked like a charm.
in windows ,the folder'name must write like this "c:\" not "c/",and you must use full path.
so the right code is render = web.template.render('d:\\documents\\python\\templates\\')
(app.py is in d:\documents\python)
You have a few typos, you need to refer to your view as Index when you use render (needs to be the same as the class name for your route):
return render.Index(greeting = greeting)
And your urls tuple needs a trailing comma:
urls = (
'/', 'Index',
)
Also make sure your template is named Index.html. Although, looking at the web.py tutorial, it looks like by convention you'd use lowercase for your route class.
Well, I suffered from the same problem, and I must say the error message is right, which indicates "you" cannot find the file, simply because you are not in the right path. So #davidheller #shellfly are right.
I use PyCharm as IDE to write python, so here is my solution:
Since I run the app.py, which is under the bin directory, thus render = web.template.render('../templates/')
which .. goes up and then found the file.
To conclude, we must be sure about the current path(even in windows), and both relative path or absolute path can be used in Windows environment, as shown below:
Absolute path.
Absolute path. Since Windows accepts both "/" and "\", we can write
render = web.template.render('C:/Users/Lucas/Desktop/Learn Python The Hard Way/ex50/gothonweb/templates/')
or
render = web.template.render('C:\\Users\\Lucas\\Desktop\\Learn Python The Hard Way\\ex50\\gothonweb\\templates\\')
Note, python interpreter interprets "\\" as "\"
Relative path.
render = web.template.render('../templates/')
You may need to compile the template like so
python web/template.py --compile templates
anyone using web.py with the Google app engine you will need to.
I am doing the same exercise and I simply go on cmd , cd to my lpthw directory which contains the folders of the project skeleton inside and do:
> python bin/app.py
I think you have to put all your files from the project skeleton in one folder and run your app from there. Hope this helps. :)