I'd like to love Django, but this business of static and media files in development environments is driving me nuts. Please rescue me from my stupidity.
I'm on my development machine. I have folder media
in the root of my project directory.
In settings.py
I have: MEDIA_ROOT = ''
and MEDIA_URL = '/media/'
.
In urls.py
I have:
if settings.DEBUG: urlpatterns += patterns('', url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT, }), )
But the only way I can get media files is by referencing /media/media/
e.g. <img src="/media/media/image.png" />
.
I expect (and want)<img src="/media/image.png" />
Can anyone tell me what is happening here, and give me a simple recipe for setting up media file handling?
Thank you very much.
@Timmy O'Mahony - thanks! epic post, and very clear. But it leaves a couple of questions:
(1) I have to use /media/
and /static/
, not media/
and static/
as MEDIA_URL
and and STATIC_URL
- am I missing something?
(2) If collectstatic
hoses /static/
, where do you put site level CSS e.g. the site's CSS files? Not in /static/
, evidently.
(3) I put them in a directory '_' off the project root and set STATICFILES_DIRS
to point to it - and that seems to be where the development server gets its static files, despite the urlpatterns
directive. If THAT is wrong, where do you put site level CSS during development, and what is the workflow around collectstatic
when you modify them - do you have to edit them one place, and collect them someplace else after every edit?
MEDIA_URL Setting Just below the MEDIA_ROOT setting add the following code to the end of settings.py file. Download this image and save it as python. png in the media directory. To access the file visit http://127.0.0.1:8000/media/python.png .
The media directory should be created under myproject directory. If you want to put images and videos into separate folders then you can create images and videos directories under media directory.
Folder Setup:
Your project root should be something like:
/app1 /app2 /media /static /templates urls.py settings.py manage.py
The media folder is supposed to hold things like images, downloads and other material that might be uploaded during normal use of the website (i.e. after development is finished)
The static folder is supposed to hold all the CSS/JS and other material that is a part of the development of the site
Settings.py:
MEDIA_ROOT is the absolute server path to the static folder mentioned above. That means it should be something like:
MEDIA_ROOT = "/User/Bob/Sites/MySite/Project_root/media/"
MEDIA_URL is the relative browser URL you should access your media files from when you are looking at the site. It should be (usually)
MEDIA_URL = "media/"
which means all material can be viewed at http://example.com/media/
Similarly, STATIC_ROOT should be something like
STATIC_ROOT = "/User/Bob/Sites/MySite/Project_root/static/"
and STATIC_URL be
STATIC_URL = "static/"
Serving the files:
Now that you have told django where these folders should be, and the correct URLs to access them, you need to serve all requests to the folders correctly.
Usually when you are in production, you want the webserver to take care of serving your static files and media files.
If you are developing though, you can just get the django development server to serve them for you.
To do this, you tell it to route all request that come in to http://example.com/media to your MEDIA_ROOT and all requests that come in to http://example.com/static to your STATIC_ROOT.
To do this, you add some URLS to URLS.py like you have:
from django.conf import settings if settings.DEBUG: urlpatterns += patterns('', url(r'^media/(?P<path>.*)$', 'django.views.static.serve', { 'document_root': settings.MEDIA_ROOT, }), url(r'^static/(?P<path>.*)$', 'django.views.static.serve', { 'document_root': settings.STATIC_ROOT, }), )
Extra:
If you have multiple apps, each with their own CSS and JS files, you mightn't want to throw them into one single /static/ folder. It might be useful to put them in subfolders of the apps they belong to:
/app1/static/ # Specific static folder /app2/static/ /media/ /static/ # Root static folder
Now, your webserver/development server is only looking for static files where you told it to look (i.e. the root static folder) so you need to collect all the files in the subfolders and copy them to the root static folder. You could do this by hand, but django provides a command to do this for you (this is the whole point of the static app)
./manage collectstatic
Why have you made the MEDIA_ROOT
setting blank? It needs to be the path to your media directory. Since, as you say, your media is in a subdirectory called media
, you should put that in MEDIA_ROOT
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With