I'm new to Django. I created a web page with Django, now I'm having problems with statically loading files on templates. I don't understand what's the problem because if I put it in only just one folder it works but if I change the directory of that folder it gives me a 404 not found error. It looks something like this:
<img src="/media/{{cat.image_name}}" alt="#" height="350">
Here "media" is the folder where my image files are and "{{cat.image_name}}" is the name of that image which is passed through the database and this works.
However, if I write
<img src="/admin/public/media/{{cat.image_name}}" alt="#" height="350">
were admin>public>media is where I have placed my images.
I get this error:
Not Found: /admin/public/media/freelancer.jpg
[09/Dec/2019 18:23:30] "GET /admin/public/media/freelancer.jpg HTTP/1.1" 404 1852
Can anyone help me, please?
Django calls these files "staticfiles" and their path conventionally contains "static". These are files that you maintain in your source repository and are not in any way uploaded by users or admins: typically all JS, CSS and image assets for JS/CSS/HTML layout.
How to configure static files is well documented on https://docs.djangoproject.com/en/2.2/howto/static-files/.
Any files that are uploaded by the users/admins (dynamic content) are placed under a path conventionally named "media", as documented on https://docs.djangoproject.com/en/2.2/topics/files/, https://docs.djangoproject.com/en/2.2/ref/settings/#std:setting-MEDIA_ROOT.
In your case:
If /admin/public/media/ is a local file path it is not visible per default in your web server (which is good). File path != URL - which is why there is STATIC_ROOT (file path) and STATIC_URL (the url), and same with MEDIA_ROOT and MEDIA_URL. Django takes care that what you provide under the file path STATIC_ROOT is visible under STATIC_URL by default. If you want do not use this mechanism you have to implement it yourself:
copy the files from the file path /admin/public/media to a directory that is on your webserver and accessible by the web server
implement a URL route - either in Django or in your proxy (Nginx or Apache HTTP)
For larger applications, it is sensible to setup an Nginx or Apache Webserver to serve the static files from a directory in which Django has placed them when running ./manage.py collectstatic. These proxies serve static files much faster than Django, while the Django server has than more resources to server the dynamic (DB) content.
Django static files work with settings, if you do not add whatever path to your staticfiles dirs it will not work
Related
I am trying to show some preview in Flask from user-uploaded images static/uploads and found that URLs generated by url_for('static', filename=image_file_path) do not work as I'd like.
I am getting out a path like: /static/uploads/0321.jpg
and after putting it in HTML img src={{ image_url_list[0] }} I see no preview (with URL: http://127.0.0.1:5000/static/uploads/0321.jpg if I copy the empty image address)
It is 404 error:GET /static/uploads/03020011.jpg HTTP/1.1" 404 -
The file is in its place and I can access it inside the App if remove the first slash static/uploads/0321.jpg
Actually, I'd like to get the working URLs not only for preview but have them externally visible for other sites (but not freely explorable by other users just typing static/uploads in browser).
So, please, advise me what am I doing wrong?
1. Briefly
I don't find, how I can to disable rendering some files with md and html extensions.
2. Detail
I use Pelican and write my articles use Markdown markup. For example, I want to create custom 404 page in GitHub Pages. I need to have 2 files in root directory of my site: 404.md and 404.html. I create these files in my content folder → I run pelican content command → I get output.
D:\Kristinita>pelican content
WARNING: Meta tag in file D:\Kristinita\content\404.html does not have a 'name' attribute, skipping. Attributes: http-equiv="X-UA-Compatible", content="IE=edge"
ERROR: Skipping .\404.md: could not find information about 'title'
3. Example of expected behavior
I set in pelicanconf.py:
NOT_RENDERING = ['404.md', '404.html']
I run pelican content → 404.md and 404.html files don't have modifications in output.
4. Did not help
I set in pelicanconf.py file:
STATIC_PATHS = ['']
Files with other extension, exclude md and html, copy to the output directory without modification, warnings and errors, but it no work for md and html files.
I use “hack” — I write extensions in UPPERCASE. For example, I create files 404.MD and 404.HTML files instead of 404.md and 404.html. But I don't get custom 404 page in GitHub Pages with UPPERCASE extensions.
I find OUTPUT_SOURCE setting in documentation → I set in pelicanconf.py:
OUTPUT_SOURCES = True
OUTPUT_SOURCES_EXTENSION = '.md'
I run pelican content command → I get error and warning in output, I don't get original 404.md in output. It don't solve my problem.
I would suggest moving those files into a separate directory within the content directory, e.g.:
content/
static/
404.html
404.md
Then you can configure Pelican to treat that directory as a static source:
STATIC_PATHS = [
'static',
]
and move the two files to the root of the output directory on processing:
EXTRA_PATH_METADATA = {
'static/404.html': {'path': '404.html'},
'static/404.md': {'path': '404.md'},
}
To make the processor ignore those files, per this GitHub issue, you will also need to set:
ARTICLE_EXCLUDES = [
'static'
]
I'm working to modify a cookiecutter Flask app. I'm working locally on WIN7 .
I've set up bower to install the front end dependencies under the static root by using a .bowerrc file in the document root containing:
{ "directory" : "myflaskapp/static/bower_components" }
This cookiecutter uses flask-assets to manage the project assets. Following https://adambard.com/blog/fresh-flask-setup/ I've modified myflaskapp/assets.py file :
from flask_assets import Bundle, Environment
import os
css = Bundle(
"libs/bootstrap/dist/css/spacelab/bootstrap.css",
"bower_components/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.css",
"css/style.css",
"css/home.css",
filters="cssmin",
output="public/css/common.css"
)
js = Bundle(
"libs/jQuery/dist/jquery.js",
"libs/bootstrap/dist/js/bootstrap.js",
"bower_components/moment/moment.js",
"bower_components/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js",
"js/plugins.js",
filters='jsmin',
output="public/js/common.js"
)
assets = Environment()
assets.register("js_all", js)
assets.register("css_all", css)
The debug setting is set to false, meaning the assets should be compressed and minified.
Before I send a request:
After:
shouldn't the files go in static/public/css and static/public/js
This particular cookiecutter recipe has a public Blueprint that declares that its static files go into the static directory. I'm not sure why the author included empty static/public/{css,js} directories; they are probably just leftovers from an earlier stage of development and were neglected. I've removed the static/public directory in my instantiation of this recipe (well, a similar one with a similar problem) to no harm.
I have simple Bottle application which serves a page for /Startpage location. The index.html page is located under /banana folder and the banana folder is located under the same folder where my views.py exist.
When I try this, its unable to find the page and throws internal server error
#app.wrap_app.route('/StartPage',method='GET')
def doStartPage():
return template('banana/index.html')
How can I refer my /banana folder in my template?
The bottle FAQ specifies the following
Bottle searches in ./ and ./views/ for templates. In a mod_python or mod_wsgi environment, the working directory (./) depends on your Apache settings. You should add an absolute path to the template search path so bottle searches the right paths.
You will need to add the bananas folder to the TEMPLATE_PATH
base_path = os.path.abspath(os.path.dirname(__file__))
bananas_path = os.path.join(base_path, 'bananas')
bottle.TEMPLATE_PATH.insert(0, bananas_path)
EDIT: Improved the answer with Graham's suggestion to use paths relative to where the code is located.
You can do something like this :
Create a rooting rule for your folder :
#route('/banana/<filepath:path>')
def file_stac(filepath):
return static_file(filepath, root="./banana")
And then, you only need to refer to this folder like this :
#route('/foo')
def bar():
return template('banana/foo.tpl')
You can do the same for as many folder as you want, and this is usefull for serving css/js files inside a template (on your template, you can then do :
<link href="banana/css/bootstrap.min.css" rel="stylesheet">
Hope it helped !
Almost 8 years late, but I did as follow for my issue, but replacing my folder with yours:
#route(/banana/<filename>)
def banana(filename):
return static_file(filename, root='./views/banana/')
I'm prototyping an idea for a website that will use the HTML5 offline application cache for certain purposes. The website will be built with Python and Flask and that's where my main problem comes from: I'm working with those two for the first time, so I'm having a hard time getting the manifest file to work as expected.
The issue is that I'm getting 404's from the static files included in the manifest file. The manifest itself seems to be downloaded correctly, but the files that it points to are not. This is what is spit out in the console when loading the page:
Creating Application Cache with manifest http://127.0.0.1:5000/static/manifest.appcache offline-app:1
Application Cache Checking event offline-app:1
Application Cache Downloading event offline-app:1
Application Cache Progress event (0 of 2) http://127.0.0.1:5000/style.css offline-app:1
Application Cache Error event: Resource fetch failed (404) http://127.0.0.1:5000/style.css
The error is in the last line.
When the appcache fails even once, it stops the process completely and the offline cache doesn't work.
This is how my files are structured:
sandbox
offline-app
offline-app.py
static
manifest.appcache
script.js
style.css
templates
offline-app.html
This is the content of offline-app.py:
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/offline-app')
def offline_app():
return render_template('offline-app.html')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
This is what I have in offline-app.html:
<!DOCTYPE html>
<html manifest="{{ url_for('static', filename='manifest.appcache') }}">
<head>
<title>Offline App Sandbox - main page</title>
</head>
<body>
<h1>Welcome to the main page for the Offline App Sandbox!</h1>
<p>Some placeholder text</p>
</body>
</html>
This is my manifest.appcache file:
CACHE MANIFEST
/style.css
/script.js
I've tried having the manifest file in all different ways I could think of:
CACHE MANIFEST
/static/style.css
/static/script.js
or
CACHE MANIFEST
/offline-app/static/style.css
/offline-app/static/script.js
None of these worked. The same error was returned every time.
I'm certain the issue here is how the server is serving up the files listed in the manifest. Those files are probably being looked up in the wrong place, I guess. I either should place them somewhere else or I need something different in the cache manifest, but I have no idea what. I couldn't find anything online about having HTML5 offline applications with Flask.
Is anyone able to help me out?
I would have thought this one would work:
CACHE MANIFEST
/static/style.css
/static/script.js
But in any case, you should not hardcode the URLs for your static files. It's best to serve the manifest as a template (moved to the "templates" folder) so that you can use url_for to generate the path to the static files, something like this:
CACHE MANIFEST
{{ url_for('static', filename='style.css') }}
{{ url_for('static', filename='script.js') }}
Then in your HTML template you would have a reference to a route instead of a static file:
<html manifest="{{ url_for('manifest') }}">
And finally, you would add a new view function that returns the manifest:
from flask import make_response
#app.route('/manifest')
def manifest():
res = make_response(render_template('manifest.appcache'), 200)
res.headers["Content-Type"] = "text/cache-manifest"
return res