I'm setting up a Heroku site to deploy a Django app for a school project. The problem is with static files using whitenoise in Django.
Quick context: My app consists of a form that takes 4 values that I use for quick math calculation inside a script. The aim of this script is to perform the calculations, draw a plot using matplotlib and save it in the static folder of my django app replacing the old one if it already exists. This static file is used to display in a html page on the site. Locally It works like a charm updating the plot each time I submit a new form. But when I try on Heroku it throws an
[Errno 2] No such file or directory: '/Users/jeff/Desktop/trydjango/src/static/yield_curve.png'
when I submit the form.
Here's the settings.py I have concerning static files:
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),]
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
My directory look like this :
src
|-- /TER
|-- -- /settings.py
|-- /graph
|-- /static/...
|-- /staticfiles/...
|-- /manage.py
I would like for my site to refresh the image each time I submit a form using the new yield_curve.png I saved in the static folder.
If I had to guess, I would say that it has to do with the fact that static files have to be "static" and not change with time.
and save it in the static folder of my django app replacing the old one if it already exists
Yes, this is possible with Django. No, it's not possible on Heroku due to its ephemeral filesystem. You can overwrite your files, but that change will be lost the next time your dyno restarts. This happens frequently (at least once per day).
Heroku officially recommends storing user uploads and static files on a third party service like Amazon S3. Whitenoise disagrees. You can use Whitenoise on Heroku, but you can't (persistently) modify your static files without redeploying.
Note that this is true regardless of the plan your dynos use. Free or enterprise, dyno filesystems are ephemeral.
I believe you cannot save/update files with the free/basic Heroku account. Static files have to remain static and unchanged. I tried to do the same thing years ago with a school project myself. Here is how I pass values to my JS charts to render a figure dynamically so I don't have to use a file:
views.py
def some_function(request):
# Do your calculations on the data here
data = [1,2,3,4] # Let's say this is the results
# Pass data in your context to the template
context = { "my_data" : data }
my_template.html
<!-- Before including your JS file -->
<script> var my_passed_data = {{ my_data|safe }} </script>
<script "include your JS file (test.js in this example) which uses the my_passed_data to make a figure>
test.js
// Whatever library you use to render a chart will be here, I'm using CanvasJS for this example
var chart = new CanvasJS.Chart("chartContainer", {
** all your options, etc. **
data: [
{
** all the other stuff such as type, name, etc. **
dataPoints: [
{ x: 0, y: my_passed_data[0] }, // here is where you access your passed data by index
{ x: 2, y: my_passed_data[1] },
This is how I pass data from my View to Template to JS to render charts using CanvasJS and without needing any files. I'm not sure if this is the best way but it works for me, hope this helps and good luck with your school project!
Related
I've been looking at a few guides on applying bootsrap to django, and I am as far as having a static file in the root of my site, containing the css and js files within bootstrap, but when it comes to linking the files I am having an issue.
So I am trying to link the stylesheet inside of my base.html file but am not sure how to format it as for some reason using {% %} inside of the href field is being interpreted as part of the directory. In one of the videos I have watched he links it like thisBut I'm not really sure how to interpret this as trying to apply it to my own like so
href = "{% static 'artForAll/css/bootstrap.css' %}"
With the file structure for reference:
\AFA\src\artForAll\static\artForAll\css
I am given an error about a non existent file as it is taking the {%%} as part of the directory
My settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR,"static"),
]
File structure(blue highlighted file is where BASE_DIR leads:
iam learning Django i have learned pretty much. I used static method to rendered css and other static files. But changes iam making to css which is in static files are not reflacting on webpage . i have to close all files and restart vscode again to see those changes. I have not added code because im not getting any error at all .
( example :: i have changed font size of all anchors . Normally it should be changes on webpage after saving and refreshing the page. but in this case font size is not changing. i have to close all files and reopen them and after starting the server again i can see those changes which i made to anchor tag. )
Any one who knows why because to see changes restart whole project will never be a good option. thanks in Advance
At the beginning of your code use {% load static %} and where ever you want to use the files from static folder use {% static 'name of your file' %}
Make sure you've not added your static folder in your base directory. In such case update your settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
STATIC_ROOT = os.path.join(BASE_DIR, 'assets')
you can use whichever name you like instead of assets
So I've been hitting my head against the wall on this for the last hour and can't seem to figure out why none of the static media (CSS, Images, JS etc) when my template is rendered.
Could someone please help me find out why adjustments I need to make? Below are snippets from Settings.py, Index.html and stylesheet please let me know if more is needed.
My static files are located in the following directory:
/djangoproject/website/static
Settings.py - Located /djangoproject/djangoprojectname/
STATIC_ROOT = os.path.normpath(os.path.join(PROJECT_ROOT,
"/static/"))
STATIC_URL = '../website/static/'
Here's a snippet from my index.html that is supposed to be calling the css style sheet with {{ STATIC_URL }}
Index.html - Location /djangoproject/website/templates/
<link rel="stylesheet" href="{{ STATIC_URL }}css/style.css">
Location of CSS StyleSheet
style.css - Location /djangoproject/website/static/css/
From the Django docs:
If {{ STATIC_URL }} isn't working in your template, you're probably
not using RequestContext when rendering the template.
As a brief refresher, context processors add variables into the
contexts of every template. However, context processors require that
you use RequestContext when rendering templates. This happens
automatically if you're using a generic view, but in views written by
hand you'll need to explicitly use RequestContext To see how that
works, and to read more details, check out Subclassing Context:RequestContext.
It seems to me that you are setting STATIC_URL to a path, when it should be set to, well, a URL. You need to set this to the web address of the folder that contains your css files, for example:
STATIC_URL = 'http://mydomain.com/static_files/'
Try to find your CSS file online by typing the address you expect it to be into your browser. Once you find the CSS file this way, just copy the root URL that got you there.
I am working on writing a Django app for the first time, so bear with me if I'm a little behind on things.
Here is an excerpt from my settings.py:
STATIC_ROOT = os.getcwd().replace('\\','/') + '/static'
STATIC_URL = '/static_files/'
STATICFILES_DIRS = (
os.getcwd().replace('\\','/') + '/static'
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
Note: I'm hoping that the os.getcwd()... line works. I am pretty sure it's not my problem, but please let me know if this is an issue. It's a placeholder for local dev purposes, so don't worry about it remaining there when I deploy.
My first issue is that template variables don't seem to be working.
An excerpt from my main template file:
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL|default:'/static_files/' }}css/base.css" />
I originally just had {{ STATIC_URL }} in there, but that simply returned nothing, so I tried adding |default:'...'. This did successfully generate the given string in the resulting HTML, but still didn't work, which brings me to my second (and more important, honestly) issue.
I can't get static files to work at all. I have tried several different methods here. I have tried putting absolute and relative paths (in various combinations) in each of the above STATIC_* variables, I have tried using the equivalent MEDIA_URL vars instead, and I have tried putting the following into my urls.py:
urlpatterns = ('',
# ...
(r'^static_files/(?P<path>.*)$',
'serve', {
'document_root': '/path/to/django/dir/static_files/',
'show_indexes': True
}
),
)
(I grabbed the above snippet from http://www.arthurkoziel.com/2008/09/02/handling-static-files-django/.)
Now I should note that I will hopefully be eventually serving up static files from a parallel Apache process once initial dev is completed, but I would still really like to know what I'm doing wrong. I haven't been able to find a decently comprehensive tutorial on static files online or on StackOverflow.
All help is greatly appreciated.
EDIT: In case it is important, I am on Windows 7 using Python 2.7.
One possibility - STATIC_URL won't be filled out in your templates unless you're passing in a RequestContext.
Make sure you have something like this in your views:
return render_to_response(template, context, context_instance=RequestContext(request))
As of Django 1.3 you can also use the new shortcut:
return render(request, template, context)
Also, make sure you have 'django.core.context_processors.static' in your context processors.
EDIT: Possible answer to the second problem, try changing
STATICFILES_DIRS = (
os.getcwd().replace('\\','/') + '/static'
)
to
STATICFILES_DIRS = (
os.getcwd().replace('\\','/') + '/static',
)
EDIT 2: More possible fixes
You can delete STATICFILES_FINDERS. You only have it set to the default, so unless you intend to expand it later on, get rid of it (one less thing to go wrong).
You can also get rid of the urlpatterns entry. Not necessary.
Your STATIC_ROOT is probably incorrect. This should be the place where Django will gather all the static files from across your project (including the directories described in STATICFILES_DIRS) when you move to production.
An example from a typical settings.py of mine:
PROJECT_DIR = os.path.dirname(__file__)
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(PROJECT_DIR, 'static'),
)
STATIC_ROOT = '/var/www/myproject_staticfiles/'
That's it!
If you want to test whether Django is finding and placing your static files correctly, try running
python manage.py collectstatic
In my case, that would go through my project directories, find all the static files, then copy them across to '/var/www/myproject_staticfiles/', where I can host them with apache.
The Django dev server automagically serves static files from within your project folder, so no collect_static is required while in dev. You don't even need to set STATIC_ROOT until you go into production.
I need to server static files in my Django project.
I would like to place them in /static directory and be able to reference them in my templates.
I've been reading "Managing static files" in the documentation and I am confused. I've followed the instructions but am not able to get it to work.
1) I have put my static files in /static under each app in my project.
2) django.contrib.staticfiles is included under my INSTALLED_APPS.
I've set the following variables in settings:
STATIC_ROOT = '/static/'
STATIC_URL = '/static/'
In my template I have the following line:
<script type="text/javascript" src={{ STATIC_URL }}/a_ajax.js></script>
however when I bring up the page and look at source the line is:
<script type="text/javascript" src=/a_ajax.js></script>
It seems like nothing was passed to the template.
What am I doing wrong?
Considering that you are using Django 1.4 or higher, here is my explanation:
In Django 1.3 the static files were separated from the uploaded files (media) and now, they have their own home.
To serve static files (css, js, images, etc) in the development environment you need:
Put these files in their respective app's static subdirectory
Make sure you have django.contrib.staticfiles.finders.AppDirectoriesFinder in your settings.py (this is the default behavior)
The directory structure will be:
__| project_root/
____| your_app/
______| static/
________| test.css
________| some.js
So the request to http://localhost:8000/static/test.css will be routed to your_app/static/test.css.
Note that you don't need to change STATIC_ROOT setting, until you go to production environment that you will need to run ./manage.py collectstatic.
The collectstatic command will collect files from the app's static subdirectories and put them all in an unique place (the directory defined in STATIC_ROOT)
If you are going to deploy your project in production, see ./manage.py collectstatic documentation.
Include 'django.core.context_processors.static' is in your TEMPLATE_CONTEXT_PROCESSORS var in settings.py.
see documentation: Referring to static files in templates
Update:
And in the view, use the RequestContext object instead of the Context object.
def view1(request):
...
context = RequestContext(...
return render_to_response( ... , context )
In newer versions of Django, this is how I link to static files in a html template:
<script type="text/javascript" src="{% static 'admin/js/labeler.js' %}"> </script>
Django docs on STATIC are here:
https://docs.djangoproject.com/en/1.9/howto/static-files/