10

I'm trying to use the Django nonrel project for google app engine. I setup the test project as described here. I added a new folder to the project named "static" for my static files. And for the app.yaml file i added the lines;

- url: /static   
static_dir: static

I can't reach my static files. Do i have to do additional configuration?

Thx in advance.

syloc
  • 4,569
  • 5
  • 34
  • 49

3 Answers3

13

As people already pointed out, you should put your static_dir directive before /.* pattern

However, that is not the only thing you should know about.

By putting this directive into app.yaml, you make AppEngine webserver (whether it's development or production server) handle the path /static, and you need all the static files to be inside static directory. This means you will have to run python manage.py collectstatic every time you change anything in your static files (especially if you have/use apps with static files -- like, say, admin or django-tinymce) just to test these changes on local server

So how to avoid that? By default staticfiles provides helpers to serve these files on development server without running collectstatic every time, the problem is the direcotry name conflict described in the previous paragraph: Django can't catch requests to your static files path, as they are handled by appserver. You can resolve it by using different paths on development and production server:

# in settings.py
if DEBUG: 
    STATIC_URL = '/devstatic/'
else:
    STATIC_URL = '/static/'

(djangoappengine sets DEBUG to True on development server). You can leave ADMIN_MEDIA_PREFIX = '/static/admin/', but remember to run collectstatic at least once before using admin

Of course remember to use {{ STATIC_URL }}path/to.css in templates instead of /static/path/to.css

Oh, and I assume that you distinguish the directory for original static files you work on and the directory where static files should be collected. I use this in my settings.py:

STATIC_ROOT = os.path.join(os.path.dirname(__file__), 'sitestatic')
STATICFILES_DIRS = (
    os.path.join(os.path.dirname(__file__), 'static'),
)

This means: you put your static fiels into static dir (and into your apps' static dirs), collectstatic collects them into sitestatic dir. Appropriate app.yaml directive is

- url: /static
  static_dir: sitestatic

Finally, you can configure app.yaml to ignore static and media directories when uploading your app, since all the static files will be collected into and served from sitestatic. However, you should set this only while uploading (otherwise these files will not be available in debug server)

LXj
  • 413
  • 3
  • 6
  • You may also need to add the staticfiles helper urlpatterns, and employ the 'static' templatetag for templates rendered without a RequestContext - see the [docs](https://docs.djangoproject.com/en/dev/howto/static-files/). Also, make sure the paths to the static files served by staticfiles dev helper don't match any static_dir or static_files entries in app.yaml. GAE distinguishes 'static' and 'script' files, and the dev appserver will block Django from dynamically serving files it thinks are static - to be consistent with production, where it is blocked for security reasons. (GAE SDK 1.7.5) – jgiles Feb 17 '13 at 20:38
  • 1
    don't forget to set static helper function in urls.py https://docs.djangoproject.com/en/dev/howto/static-files/#serving-static-files-in-development – taelimoh Nov 20 '15 at 19:45
11

app.yaml have nothing to do with Django, but it does configures App Engine front-end. The answer depends on whether you want to serve static files with Django or the front-end (which is, well, cheaper and faster).

If you just "added" your - url: /static mapping to the end, move it before the /.* wildcard. As all mappings processed from top to bottom — first matching mapping wins.

Igor Kharin
  • 699
  • 6
  • 7
4

Well i just figured it out. Just use static_dir line before the main.py. So the app.yaml should look like this;

application: test
version: 1
runtime: python
api_version: 1

builtins:
- remote_api: on

inbound_services:
- warmup

handlers:
- url: /_ah/queue/deferred
  script: djangoappengine/deferred/handler.py
  login: admin

- url: /_ah/stats/.*
  script: djangoappengine/appstats/ui.py

- url: /media/admin
  static_dir: django/contrib/admin/media
  expiration: '0'

- url: /static
  static_dir: static

- url: /.*
  script: djangoappengine/main/main.py
syloc
  • 4,569
  • 5
  • 34
  • 49