serve media files on my local development server

575 views
Skip to first unread message

Sebastian Clemens

unread,
Feb 4, 2014, 8:56:20 AM2/4/14
to mezzani...@googlegroups.com
Hey,

I'm using Ubuntu 13.10 and build sites on the development server (manage.py runserver), but it doesn't serve media files. I tried it with STATICFILES_DIR, but that changed nothing. On my productiv Debian 6 Server, everything works perfect. But locally I just get an "A server error occurred. Please contact the administrator."

What else can I try to solve this?

Josh Cartmell

unread,
Feb 4, 2014, 12:05:59 PM2/4/14
to mezzani...@googlegroups.com
Is a traceback displayed in the terminal that is running the dev server?  I've seen errors like that when an error occurred and then Django created another error trying to produce the debug error page.


--
You received this message because you are subscribed to the Google Groups "Mezzanine Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mezzanine-use...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Sebastian Clemens

unread,
Feb 4, 2014, 12:10:56 PM2/4/14
to mezzani...@googlegroups.com
Oh, of course

Traceback (most recent call last):
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 85, in run
    self.result = application(self.environ, self.start_response)
  File "/home/basti/Dokumente/websites/virtualenv/local/lib/python2.7/site-packages/Django-1.6.1-py2.7.egg/django/contrib/staticfiles/handlers.py", line 68, in __call__
    return super(StaticFilesHandler, self).__call__(environ, start_response)
  File "/home/basti/Dokumente/websites/virtualenv/local/lib/python2.7/site-packages/Django-1.6.1-py2.7.egg/django/core/handlers/wsgi.py", line 206, in __call__
    response = self.get_response(request)
  File "/home/basti/Dokumente/websites/virtualenv/src/mezzanine/mezzanine/core/management/commands/runserver.py", line 15, in get_response
    return serve(request, path, document_root=settings.STATIC_ROOT)
  File "/home/basti/Dokumente/websites/virtualenv/local/lib/python2.7/site-packages/Django-1.6.1-py2.7.egg/django/views/static.py", line 55, in serve
    raise Http404(_('"%(path)s" does not exist') % {'path': fullpath})
Http404: "media/car_images/hirn25_1.png" ist nicht vorhanden
[04/Feb/2014 18:06:57] "GET /static/media/car_images/hirn25_1.png HTTP/1.1" 500 59

Here you can see the given url is /static/media/, but it's looking for /media/
My settings are like this:

# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = "/static/"

# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
# STATIC_ROOT = os.path.join(PROJECT_ROOT, STATIC_URL.strip("/"))

STATICFILES_DIRS = (
    os.path.join(PROJECT_ROOT, "static"),
)

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = STATIC_URL + "media/"

# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = os.path.join(PROJECT_ROOT, *MEDIA_URL.strip("/").split("/"))

What's wrong here?

Sebastian Clemens

unread,
Feb 4, 2014, 12:10:09 PM2/4/14
to mezzani...@googlegroups.com
You received this message because you are subscribed to a topic in the Google Groups "Mezzanine Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mezzanine-users/SnSEsx0g3lo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mezzanine-use...@googlegroups.com.

Sebastian Clemens

unread,
Feb 4, 2014, 12:15:59 PM2/4/14
to mezzani...@googlegroups.com
If I remove STATICFILES_DIR and set STATIC_ROOT (so uses the default config), it will return my image, but it can't find my own css files located in /static/css/, maybe it just find static files in app directories.

Josh Cartmell

unread,
Feb 4, 2014, 12:17:35 PM2/4/14
to mezzani...@googlegroups.com
I would compare your settings.py to the default one (https://github.com/stephenmcd/mezzanine/blob/master/mezzanine/project_template/settings.py) and see if there are any differences.  If you start a new Mezzanine project does it work?

Sebastian Clemens

unread,
Feb 4, 2014, 12:27:51 PM2/4/14
to mezzani...@googlegroups.com
Ok, I made a new default project. Than I created a new file /static/css/test.css
Than at http://127.0.0.1:8080/static/css/test.css
I get 'css/test.css' could not be found.

As you see it removes the /static/

Can you reproduce this?

Sebastian Clemens

unread,
Feb 4, 2014, 12:26:19 PM2/4/14
to mezzani...@googlegroups.com
Ok, I made a new default project. Than I created a new file /static/css/test.css
Than at http://127.0.0.1:8080/static/css/test.css
I get 'css/test.css' could not be found.

As you see it removes the /static/

Can you reproduce this?


You received this message because you are subscribed to a topic in the Google Groups "Mezzanine Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mezzanine-users/SnSEsx0g3lo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mezzanine-use...@googlegroups.com.

Josh Cartmell

unread,
Feb 4, 2014, 3:00:28 PM2/4/14
to mezzani...@googlegroups.com
My guess is that you are putting the css directly into your projects static directory, which you shouldn't do.  You should put it in a static directory inside an app.

I just tried it, and putting it directly in the static causes an error, but if I put it in an apps static directory it works.

Give that a shot!

Stephen McDonald

unread,
Feb 4, 2014, 3:44:16 PM2/4/14
to mezzani...@googlegroups.com
Mezzanine, and actually Django itself, normally doesn't serve files under the project's STATIC_ROOT directory during development - files in that location typically aren't expected to be part of the version controlled project. The recommended approach is for all static files to be contained within the "static" directory of their relevant app (as per INSTALLED_APP), which might be as simple as a "theme" app. As you might know already, all these files then get copied to STATIC_ROOT when the collectstatic management command is run, as part of your deployment process.

As for files under MEDIA_URL (user uploaded files), Django will happily serve these during development, but actively blocks the questionable practise of having MEDIA_URL fall under STATIC_URL, as Mezzanine does by default (more info here: https://code.djangoproject.com/ticket/15199).Tired, beaten down, yet still refusing to submit to every peculiar whim of Django, Mezzanine defiantly works around this by providing its own shadowed version of runserver, which restores the ability to serve up files under MEDIA_URL during development.

Given all that, I've just modified Mezzanine's runserver to also serve up files under STATIC_ROOT, so while it's probably not an ideal location to store files, it'll work locally now as it would when deployed.




Stephen McDonald
http://jupo.org

Arnold Krille

unread,
Feb 4, 2014, 3:56:15 PM2/4/14
to mezzani...@googlegroups.com
On Tue, 4 Feb 2014 12:00:28 -0800 Josh Cartmell <joshc...@gmail.com>
wrote:
> My guess is that you are putting the css directly into your projects
> static directory, which you shouldn't do. You should put it in a
> static directory inside an app.
>
> I just tried it, and putting it directly in the static causes an
> error, but if I put it in an apps static directory it works.

As far as I remember (its been a day), if you place a static-dir
directly in your project and configure settings.py to "use" it, it will
only be used by "python manage.py collectstatic" to collect the statics
of all the apps into it. And before that it removes whatever you placed
in there:-)

- Arnold
signature.asc

Sebastian Clemens

unread,
Feb 4, 2014, 4:06:09 PM2/4/14
to mezzani...@googlegroups.com, st...@jupo.org
Josh's approach works for me - nevertheless the improvement of the runserver command also is a cool idea. Thanks very much!

Eduardo Rivas

unread,
Feb 5, 2014, 6:02:33 PM2/5/14
to mezzani...@googlegroups.com
As Stephen said, it is recommended you only use STATIC_ROOT to contain files rounded up by collectstatic when deploying. The directory "/static" is listed in .gitignore and .hgignore for this same reason. Just in case someone is wondering what to do with files that don't belong to any app, this is what I do:
  1. Create "assets/" (or whatever you want to name it) in your project root. Dump your general purpose static resources there.
  2. In settings.py define STATICFILES_DIRS = (os.path.join(PROJECT_ROOT, "assets"),). This will tell Django to see "assets/" as a valid location for static files.
  3. Access your files in the templates. For example, "assets/style.css" will be accessed by {% static "style.css" %}.

Just my two cents :)

Sebastian Clemens

unread,
Feb 6, 2014, 6:32:30 AM2/6/14
to mezzani...@googlegroups.com
Since Stephen's changes and my last git pull, the media files won't served anymore on a default project. Can anyone confirm this?

Sebastian Clemens

unread,
Feb 6, 2014, 6:42:24 AM2/6/14
to mezzani...@googlegroups.com
Now I made a local revert of


and everything works. Don't know what happened.

Josh Cartmell

unread,
Feb 7, 2014, 5:44:44 PM2/7/14
to mezzani...@googlegroups.com
Hey Steve, I'm seeing the same thing.  I've been playing around with it and the except clause in the code Sebastian referenced above is never entered even when the site 404s on a media file.

Removing the try except but leaving the other changes intact causes things to start working as well as allowing media directly in the static root to be served.

Looking at https://github.com/django/django/blob/master/django/contrib/staticfiles/handlers.py#L46 this makes sense because the super get_reponse (of MezzStaticFilesHandler) already catches the 404.


--

Josh Cartmell

unread,
Feb 7, 2014, 5:51:25 PM2/7/14
to mezzani...@googlegroups.com
Actually, scratch that, removing the try except doesn't get things working, backing out the change does though.

Stephen McDonald

unread,
Feb 7, 2014, 7:54:02 PM2/7/14
to mezzani...@googlegroups.com
I had django-compressor installed in my development environment which is one of the optional apps Mezzanine will pick up. When it's installed, it'll cause the current project to happily serve up uploaded files (via compressor's own staticfiles finder class), which made my original change look like it was doing the job - as reported though, that code never actually run.

The pain of working all this out was somewhat alleviated by the hilarity of django-compressor and django.contrib.staticfiles being written by the same person.

Here's the fix, I'll push a new release out later today:



Josh Cartmell

unread,
Feb 10, 2014, 12:48:04 PM2/10/14
to mezzani...@googlegroups.com
Thanks for sorting this out Steve!
Reply all
Reply to author
Forward
0 new messages