Django on Azure not loading static files - django

I followed the tutorial below to create a django project on azure:
http://www.windowsazure.com/en-us/develop/python/tutorials/web-sites-with-django/
Everything worked fine until I tried to install the django_admin_bootstrapped app. Now all static requests return 404 error. I don't if the new app caused the problem or just exposed it.
I have this:
STATIC_ROOT = ''
# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
#os.path.join(PROJECT_DIR, 'site-packages/django_admin_bootstrapped/static'),
)
I read quite a bit online and some people say you have to configure your server to serve static files. I don't have direct access to the server, it's an azure website and I deploy through git. And like I said, the admin and everything used to work before I tried to install these apps that bootstrap the admin. Now even when the app is not under INSTALLED_APPS I don't get any css or js files.
Thanks!

I had this problem and none of the suggested answers seemed to fit. My bizarre solution was to switch off Python on the Azure web site configure page.
I arrived at this odd conclusion by installing the PTVS Django sample and following the steps in this tutorial http://azure.microsoft.com/en-us/documentation/articles/web-sites-python-ptvs-django-sql/. The only difference I could fine between my site and the working tutorial was that Django was off! If someone has an explanation I would love to hear it (PHP is enabled!!!).

I found my solution on this page: http://mrtn.me/blog/2012/06/27/running-django-under-windows-with-iis-using-fcgi/
I had to create a central static folder and add a web.config for iis to serve the files. web.config below:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<!-- this configuration overrides the FastCGI handler to let IIS serve the static files -->
<handlers>
<clear/>
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule" resourceType="File" requireAccess="Read" />
</handlers>
</system.webServer>
</configuration>
Hope this helps someone!

I don't have enough rep to vote up but the answer does in fact work on Azure for me as well, and appears to be, so far, the only method of doing it. Just remember that the web.config needs to be in the right place...lol...I apparently had multiple static folders as I was trying different ways of solving this.

If after trying all the other proposed solutions you still find yourself at trouble, you may have to understand that depending on the server that's running you application is the way static files are server. Django has it's own server, which is run by using the command:
python manage.py runserver
But PAAS providers do not use this server in most of the cases. gunicorn is in most times the chosen one. Azure sometimes uses IIS's FastCGI handler but at current date it is intelligent enough to detect a django application and try to use django's default server.
So, the first step you have to take is to find out what server is azure using to run your app, and you may know that by reading azure's log:
https:// YOUR APP NAME.scm.azurewebsites.net/api/logstream
If you confirm that azure is using django's default server, you must bear in mind that django does not server static files automatically when in a production environment. You must configure the static folder's url. So in your config/urls.py set the static url, like this:
from django.conf import settings
from django.conf.urls.i18n import i18n_patterns
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import include, path
urlpatterns = i18n_patterns(path('admin/', admin.site.urls), prefix_default_language=False) + \
static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + \
static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
As you can see, I enable admin, static and media urls. This is enough to let django's default server know where to find and serve static files (and media files too, as well as admin routes)

Yes, I can confirm that the 'right place' to store your static files for a Django deployment on Azure Web Sites is the 'static' directory in the web root.
Step 1: create a directory called static in your web root (www root)
Step 2: edit Django's settings.py and set STATIC_ROOT = 'D:/home/site/wwwroot/static'
Step 3: In your templates use the construct {% static "static_file_name" %}.

Related

How to serve Django static files during development without having to run "collectstatic"?

I have a Django version 2.2.6 application that has my Django static files being served up from a separate dedicated file server. I use the Django "collectstatic" command to update the static files on my file server whenever one of them changes. I also use the django-pipeline package so that each static file contains a special string in the file name. This prevents my users' browsers from loading a static file from cache if I've updated that file. This configuration works perfectly.
I'm now in a phase in which I'm making constant changes to my CSS file to create a new look and feel to my website and it's a pain to have to remember to run the collectstatic command after each little change I make. Is there a way I can temporarily "toggle" this collectstatic configuration off while I'm doing development so that I don't have to constantly run the collectstatic command? I seem to recall there was a way to change the main urls.py file and set DEBUG = True to do something like this back in Django 1.8 but I don't see it mentioned in the latest Django documentation. What is the current "best practice" for doing this?
I think it still is in the docs.
https://docs.djangoproject.com/en/2.2/howto/static-files/#serving-static-files-during-development
In urls.py:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

Using Django static() to generate audio files' URLs in production

I'm trying to get my Django app to play audio files (supposedly) uploaded by users via a form. Said files are tied to a model :
# models.py
class Doc(models.Model):
# ...
tape = models.FileField()
The uploading and saving parts are working fine, and the files are stored where they should be :
- djangoproject
|
- docapp
|
- media <- here
So, in order to get where I want, I added these two lines to the settings.py file MEDIA_ROOT = os.path.join(BASE_DIR, 'docapp/media/') and MEDIA_URL = 'docapp/media/'.
I hoped to be able to link to the audio files thus:
# templates/docapp/index.html
...
<audio src='{{ doc.tape.url }}' controls></audio>
Unfortunately, this wasn't working because the link generated by doc.tap.url (http://localhost/docapp/media/filename.aac) was returning a 404 error.
After a lot of googling I found this answer, which I happily copy-pasted into my app ... and it worked. This is the code in question :
# urls.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
The problem is that I'm not comfortable with inserting code in my apps that I don't understand. I did some research about the static() function and all I could get is this :
Helper function to return a URL pattern for serving files in debug mode
Does this mean that the static function should not be used in production? If so, what should I be using in production? And what exactly does it do?
EDIT To be clear, the generated URL after injecting the solution is the same as the one generated without it. Yet, it only works when the static() function is present.
EDIT 2 I forgot to mention that the 404 errors persisted even after I chmoded the media folder to allow others to read-access it.
Thanks in advance!
You shouldn't do anything. No errors no problem. The docs write about development server and serving static files AND that it is for development only. In a production environment you configure your server (Apache, NGNIX or third party like S3) to serve the files. That's all.
Try to configure media files and access the file via it's url. If it works, try the {{ doc.tape.url }} template tag.
In your development environment your media may live in /media/ (route and directory). While on production it may be something like media.example.com. Running Django with the settings for that environment will change all static/media domains and paths to their correct locations.
You may split settings file into a settings file for each environment (production, acceptance, development). Like this:
project/
settings/
__init__.py
base.py
local.py
staging.py
test.py
production.py
You can run your project with a specific env: ./manage.py runserver --settings=project.settings.development. Do not repeat yourself and put development specific settings in development.py and from base import * so that base.py contains the default settings.
This project and settings layout is taken from the book Two Scoops of Django. It is just an example. Adjust to your own needs.
Yes, django.conf.urls.static.static is only for development and not for production. For production, you should just need to configure your MEDIA_URL and MEDIA_ROOT settings and have your webserver serve the MEDIA_ROOT directory in the MEDIA_URL path.
Basically adding that in the URL urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) will make the media files in the URL existing. Try removing that and visit your media file in the URL and you will receive a 404 not found. It's very similar to the concept that you are inserting a view for rendering the media files

Identical and simple way of serving static files in development and production - is it possible?

Is it possible to have static files only in PROJECT_DIR/static directory without duplicates of static files in app dirs and without needing to do collectstatic command? On local computer Django dev server is used, in production - some other web server. From what I have read so far I decided that it's impossible, but maybe it's not true.
Of course it's possible.. the static files app is there to be useful. If you dont like "duplicates" (that's the whole point - you can have files per app, all merged into one area), don't use the staticfiles app.
Just use any folder, anywhere, as your assets folder. In production, serve it at some url, say MY_URL. In development, wire up your URLConf to serve files at your asset folder at MY_URL
https://docs.djangoproject.com/en/1.5/howto/static-files/#serving-files-uploaded-by-a-user
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = patterns('',
# ... the rest of your URLconf goes here ...
) + static('MY_URL', document_root='path-to-my-files')
This is the old school method of doing this, before staticfiles brought its goodness.
Are you sure you can't solve this problem by just using the staticfiles app? It's not much work to add in a python manage.py collectstatic --noinput in your deployment script.

Django - Can't Get Static Files To Work In Development

First of all apologies for my earlier post which I accidently submitted before finishing the question... I'm not spamming :)
This seems to be a source of much confusion judging by the amount of similar titles on the subject, however after reading everything I could find on static files with the django development server i've almost given up hope!
So my static files are served from C:/Users/Dan/seminarWebsite/static/, in which i have sub folders for images, css etc. For simplicity lets just say I want an image to show on my website homepage (an easy task I would have hoped!)
SETTINGS:
STATIC_ROOT = 'C:/Users/Dan/seminarWebsite/static/'
STATIC_URL = '/static/'
The static files app is also active.
URLS:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()
TEMPLATE: "{{ STATIC_URL }}images/vision.jpeg"
However only a broken link appears and at this address: http://127.0.0.1:8000/homepage/images/vision.jpeg; and i don't think it should be at that address (homepage is the url name of the page the staic image file is being called to)
Any help would be fantastic as its grinding my project to a hault.
Thank you
The url for your file should be http://127.0.0.1:8000/static/images/vision.jpeg
If your template has the following:
TEMPLATE: "{{ STATIC_URL }}images/vision.jpeg"
That means STATIC_URL isn't showing anything, which means you're probably not using RequestContext or you don't have the static context processor.
When debugging things like this, make sure you actually look in the template for what URL is being generated.
https://docs.djangoproject.com/en/dev/ref/templates/api/#subclassing-context-requestcontext
Check in your settings if DEBUG = False. If False - the built-in server will not serve static files unless you force it to do so with:
django-admin.py runserver --insecure
Here is a link to django docs about the The staticfiles app
--insecure
Use the --insecure option to force serving of static files with the
staticfiles app even if the DEBUG setting is False. By using this you
acknowledge the fact that it's grossly inefficient and probably
insecure. This is only intended for local development, should never be
used in production and is only available if the staticfiles app is in
your project's INSTALLED_APPS setting.
Finally worked! Everyones advice was very helpful thank you. For some reason I had a static subdirectory in my static directory and Django was looking in that...
Static
-Admin
-CSS
-Images
:Vision.jpeg
-....
-Static
-Admin
-CSS
-Images
:Vision.jpeg
http://127.0.0.1:8000/static/static/images/vision.jpeg
Don't really understand why but it works so thank you though

serving static files on Django production tutorial

Does anyone have a simple step-by-step tutorial about serving static files on a Django production app? I read the Django docs and it sounds really complicated... I'm trying to go the route of serving static files using a different server like lighttpd, nginx, or cherokee, but setting these up is all Greek to me. I downloaded lighttpd, tried to follow the instructions to install, and within a few seconds got an error. Missing this or that or whatnot... I'm not a UNIX whiz and I'm not very good at C/C++, so all this ./configure and MAKE install are gibberish to me... So I guess my immediate questions are:
Which server would you recommend to serve static files that's easy to install and easy to maintain?
Assuming I actually get the server up and running, then what? How do I tell Django to look for the files on that other server?
Again, anyone has step-by-step tutorials?
Thanks a lot!
Sorry, don't have a step by step tutorial. But here is a high level overview that might help:
You probably want to go with the Apache server ( http://httpd.apache.org/) This comes with most *nix distributions.
You then want to use mod python (or as the commenter pointed out mod_wsgi: http://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/) to connect to Django : http://docs.djangoproject.com/en/dev/howto/deployment/modpython/?from=olddocs. Once you complete this step, Apache is now fronting for Django.
Next you want to collect the static files in your Django into one directory and point apache at that directory. You can do this using the the ./manage.py collectstatic if you used django.contrib.staticfiles (http://docs.djangoproject.com/en/dev/howto/static-files/.)
So the trick is you're not telling Django to delegate serving static files to a specific server. Rather you're telling httpd which urls are served via Django and what urls are static files.
Another way of saying this is that all requests come to the Apache web server. The webserver, according to the rules you specify in httpd.conf, will decide whether the request is for a static file or whether it is for a dynamic file generated by django. If it for a static file it will simply serve the file. If the request is for a dynamic file it will, via modpython, pass the request to Django.
Hope that helps.
Development
STATICFILES_DIRS should have all static directories inside which all static files are resident.
STATIC_URL should be /static/ if your files are in local machine otherwise put the base URL here e.g. http://example.com/.
INSTALLED_APPS should include django.contrib.staticfiles.
In the template, load the staticfiles module:
{% load staticfiles %}
<img src='{% static "images/test.png" %}' alt='img' />
Production
Add STATIC_ROOT that is used by Django to collect all static files from STATICFILES_DIRS to it.
Collect static files:
$ python manage.py collectstatic
Add the path to urls.py:
from . import settings
urlpatterns = patterns('',
..
url(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root':settings.STATIC_ROOT)}),)
More detailed articles are listed below:
http://blog.xjtian.com/post/52685286308/serving-static-files-in-django-more-complicated
http://agiliq.com/blog/2013/03/serving-static-files-in-django/
With the latest Django version like Django 3.2.6 I was having issues serving media and static files both in the dev and prod environment while DEBUG = False.
So I got around a solution that came from multiple stack overflow posts.
Import appropriate functions to urls.py
from django.urls import include, path, re_path
from django.views.static import serve
Define static URL pattern list to urls.py
static_urlpatterns = [
re_path(r"^media/(?P<path>.*)$", serve, {"document_root": settings.MEDIA_ROOT}),
re_path(r"^static/(?P<path>.*)$", serve, {"document_root": settings.STATIC_ROOT}),
]
Assuming your STATIC_ROOT and MEDIA_ROOT is already defined in settings.py file
Just include static_urlpatterns in urlpatterns
urlpatterns = [
path("admin/", admin.site.urls),
path("api/", include(api_urlpatterns)),
path("", include(static_urlpatterns)),
]
Hope it works for you both in the dev and prod environment when DEBUG = FALSE. Thank you.
Updated for urls.py
the url(....) format doesn't work anymore in urls.py for Django 3.0.7.
you need to do then:
urls.py:
from django.conf import settings # to import static in deployment
from django.conf.urls.static import static # to import static in deployment
....
urlpatterns = [
....
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) # to import static in deployment
Reference: https://docs.djangoproject.com/en/3.0/howto/static-files/