Serving Static files - Django-nonrel in Appengine - django

I've successfully got a basic Django-nonrel app up and running on Appengine. The templates are getting rendered properly, but the static content returns a 404 response.
There is no problem with the static content in the dev server launched using `python manage.py runserver'.
These are the relevant lines in static.py:
STATIC_URL = '/static/'
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder', # Refers to PROJECT_DIR/static
'django.contrib.staticfiles.finders.AppDirectoriesFinder', # Appname/static
)
STATICFILES_DIRS = (os.path.join(PROJECT_DIR, 'static'),)
In the relevant template:
{% extends "base.html" %}
{% load staticfiles %}
{% block title %}Adding Objects{% endblock %}
{% block content %}
<p>Placeholder for Objects</p>
<img src="{% static "test_pattern.gif" %}">
<img src="{% static "sample_overlay.gif" %}">
{% endblock %}
With this, static files in myproject/static directory and myproject/myapp/static directory are being served successfully in the dev server (python manage.py runserver).
This is my app.yaml:
application: appname
version: 1
runtime: python27
api_version: 1
threadsafe: yes
builtins:
- remote_api: on
inbound_services:
- warmup
libraries:
- name: django
version: latest
handlers:
- url: /_ah/queue/deferred
script: djangoappengine.deferred.handler.application
login: admin
- url: /_ah/stats/.*
script: djangoappengine.appstats.application
- url: /media/admin
static_dir: django/contrib/admin/media
expiration: '0'
- url: /.*
script: djangoappengine.main.application
Any clue how to fix this? I don't want the Appengine web server to handle static files, I want to route everything through Django (at least for now). Hence a solution like this isn't really acceptable in my case.
EDIT: I can easily get around this with this in my app.yaml and serving all static files from projectdir/static.
- url: /static
static_dir: static
But this solution seems dirty, I'd like to leave it all to Django.

Your adding the /static mapping in app.yaml is the correct method. It is not "dirty".
Also, you are adding the django library in app.yaml. That is not correct. Django-nonrel uses its own branch of Django, which you should import as a directory with your app. Adding the django call to libraries in app.yaml means you are importing 2 versions of Django, which can cause strange errors. Delete the Django library call in app.yaml, and import the Django version that is included with nonrel.

Related

Why is staticfiles not able to find or serve .css, using FORCE_SCRIPT_NAME in docker

EDIT/Workaround:
I got this working. I think there is an unfortunate interaction of FORCE_SCRIPT_NAME, the requirement for STATIC_URL to end in /, and the behavior of django.conf.urls.static. I'll mark this answered when I'm able to put together a step-by-step explanation.
Meanwhile, here's the recipe that works for me:
urls.py
from django.conf.urls.static import static
urlpatterns += static("static", document_root=settings.STATIC_ROOT)
settings.py
FORCE_SCRIPT_NAME = "/the-prefix-i-need/"
STATIC_ROOT = "/static/"
STATIC_URL = "static/"
STATIC_URL has to end with "/" (or runserver fails). But if static's first argument ends with / it pulls in the FORCE_SCRIPT_NAME into the URL pattern it is looking for, and doesn't match "/static"
In development (DEBUG=True) mode, running in docker on a host where the site is served with a prepended path corresponding to a branch, I am unable to get static files working.
Using python 4.0.6
In settings.py I have these settings:
DEBUG = True
BASE_DIR = Path(__file__).resolve().parent.parent # default generated
FORCE_SCRIPT_NAME = "https://pmdocker01d.pm.local:8443/bi-web-utils/ta0624/"
INSTALLED_APPS = [
...
'django.contrib.staticfiles',
STATIC_URL = 'static/'
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
In my html file:
{% load static %}
<html>
<head>
...
<link rel="stylesheet" href="{% static 'tableau_explorer/style.css' %}">
And my css is in:
django_root/tableau_explorer/static/tableau_explorer
On my development machine, both running manage.py from the sheel, and
in a dockerfile, it works. In that setting, I don't have FORCE_SCRIPT_NAME.
When it is on the other docker host, the generated HTML
<link rel="stylesheet" href="/static/tableau_explorer/style.css">
And I get a 404 error.
If I change:
STATIC_URL = 'https://pmdocker01d.pm.local:8443/bi-web-utils/ta0624/static/'
Then it instead of a plain 404 I get message that it's getting HTML instead of css, because the server is returning this
Request Method: GET
Request URL: http://https://pmdocker01d.pm.local:8443/bi-web-utils/ta0624/static/tableau_explorer/style.css
Using the URLconf defined in bi_web.urls, Django tried these URL patterns, in this order:
admin/
....
The current path, static/tableau_explorer/style.css, didn’t match any of these.
For the other docker host I tried adding this to the main project
urls.py (not tableau/explorer/urls.py) I tried adding this and and
couldn't see any difference:
from django.conf import settings
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = [ . . . . ]
if settings.DEBUG:
urlpatterns += staticfiles_urlpatterns()
If I browse to https://pmdocker01d.pm.local:8443/bi-web-utils/ta0624/static/
I get the error message "Directory indexes are not allowed here.", whereas
other urls like making it end "staticx/" it just says page not found. So
I think static is doing something, but I can't tell that anything at all is
being gathered there and don't know how to check.
If I make a shell connection into the running docker host, it seems like static
is finding what I'd expect:
$ python manage.py findstatic tableau_explorer/style.css
Found 'tableau_explorer/style.css' here:
/code/tableau_explorer/static/tableau_explorer/style.css
Anyone know right off what's going on and can tell me "type this and it'll work?"
If not...
My question now is - what is the staticfiles supposed to be doing with files
in development mode, and how does it serve them?
is it supposed to intercept any request that begins with "static/"
when the app starts running, does staticfiles gather the .css files from
different applications "static" folders, and put copies into an on-disk
repository I can verify, or put verbose logging on? -- Should I be able
to see the files in a particular directory on the running server?
is the BASE_DIR setting relevant to staticfiles? I am using what was
generated by manage.py createproject
in staticfiles nowadays, is it supposed to take care of appending "static" into
the urls? I thought I shouldn't need to modify urls.py?
-- Edit:
Since posting I added STATIC_ROOT=/static in the settings.py file, and in Dockerfile I added collectstatic. When I shell into the running docker image on the host I see
$ ls -l /static/tableau_explorer/style.css
The files are present good, and are other-accessible all the way down.
The rendered HTML file has
<link rel="stylesheet" href="https://pmdocker01d.pm.local:8443/bi-web-utils/ta0624/static/tableau_explorer/style.css">
and if I browse directly to that link, Django is complaining it doesn't match any path... I feel like I have to do something in urls.py to give the request to staticfiles to handle?
The response when I browse is the familiar:
<html lang="en"><head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Page not found at /static/tableau_explorer/style.css</title>
</head>
<body>
<div id="summary">
<h1>Page not found <span>(404)</span></h1>
<table class="meta">
<tbody><tr>
<th>Request Method:</th>
<td>GET</td>
</tr>
<tr>
<th>Request URL:</th>
<td>http://https://pmdocker01d.pm.local:8443/bi-web-utils/ta0624/static/tableau_explorer/style.css</td>
</tr>
</tbody></table>
</div>
<div id="info">
<p>
Using the URLconf defined in <code>bi_web.urls</code>,
Django tried these URL patterns, in this order:
</p>
<ol>
. . . . Nothing about "/static" . . .
</ol>
<p>
The current path, <code>static/tableau_explorer/style.css</code>,
didn’t match any of these.
</p>
....

How do I resolve the "'mathfilter' tag 'addition' stopped working since replicating django project" error?

Recently I moved a Django Project to a new virtual environment. Everything appears to be working fine, with the exception of the following error:
TemplateSyntaxError at /profile/
Invalid filter: 'addition'
Request Method: GET
Request URL: http://example.com/example/
Django Version: 1.9.12
Exception Type: TemplateSyntaxError
Exception Value:
Invalid filter: 'addition'
Exception Location: /opt/example/local/lib/python2.7/site-packages/django/template/base.py in parse, line 516
Python Executable: /usr/local/bin/uwsgi
Python Version: 2.7.3
I narrowed this down to this line of code:
{% with deeb_percent=stat.deeb_base|addition:stat.deeb_deal %}
Further investigation and I found this: https://github.com/dbrgn/django-mathfilters , it appears 'addition' is a custom filter which is part of mathfilters. The documentation I linked says to run:
pip install django-mathfilters
I have checked with pip freeze, and mathfilters is installed.
appdirs==1.4.3
backports.ssl-match-hostname==3.5.0.1
beautifulsoup4==4.5.3
Django==1.9.12
django-appconf==1.0.1
django-autocomplete-light==3.2.1
django-compat==1.0.8
django-compressor==1.6
django-dual-authentication==1.0.0
django-hijack==2.0.1
django-htmlmin==0.8.0
django-ipware==1.1.2
django-mathfilters==0.3.0
django-modelcluster==3.0.1
django-taggit==0.22.0
django-treebeard==4.1.0
django-widget-tweaks==1.4.1
djangorestframework==3.6.2
html5lib==0.9999999
packaging==16.8
Pillow==3.0.0
pyparsing==2.2.0
pytz==2015.7
requests==2.13.0
simplejson==3.10.0
six==1.10.0
slackclient==1.0.5
Unidecode==0.4.20
wagtail==1.9
websocket-client==0.40.0
Willow==0.4
Then add mathfilters to your INSTALLED_APPS.
I have also checked INSTALLED_APPS in the project settings.py and mathfilters is also loaded:
INSTALLED_APPS = [
...
'mathfilters',
...
]
At the top of the template in question 'mathfilters' is loaded:
{% extends "base.html" %}
{% load i18n %}
{% load static %}
{% load extra %}
{% load mathfilters %}
If i change 'addition' in the template to 'add' the template works ok.
{% with deeb_percent=stat.deeb_base|addition:stat.deeb_deal %}
But I don't want to do this for every single template in multiple places, and also am uncomfortable leaving this 'broken' since I installed the project in a new virtualenv.
Why aren't the mathfilters working? and how can I resolve this error?
https://github.com/dbrgn/django-mathfilters
addition – replacement for the add filter with support for float /
decimal types
Update to mathfilter to 0.4.0, things will be back to normal
For Python 3, just use {{ a|add:b}}

404 not found assets files in django

I don't know why I'm getting this error continuously modifying the routes of my settings.py, I have the tree directory of my project as follows:
/dgp
/assets
/css
/js
...
/sales
manage.py
/dgp
settings.py
As you can see, I want to access the assets folder which is one folder up to settings.py, in my settings files I have the follow configuration:
PROJECT_ROOT = os.path.dirname(os.path.realpath(__file__))
STATIC_ROOT = os.path.abspath(os.path.join(PROJECT_ROOT, '..','static'))
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.abspath(os.path.join(PROJECT_ROOT,"..","assets")),
)
But always I'm getting a 404 error finding assets files:
"GET /static/assets/css/bootstrap.min.css HTTP/1.1" 404 1688
I don't know why it's concatenating /static with /assets but I prove hard-coding with absolute pahts and neither... I don't know what's wrong... any ideas?
How are you referencing the static files in your templates? It looks like you are including assets/ in that path when you shouldn't be.
For example, if you are using {% static "assets/css/bootstrap.min.css" %} try switching it to {% static "css/bootstrap.min.css" %}. If you are using the {{ STATIC_URL }} variable within the templates to get the path, you would also just drop the assets/ part of the path in the same way.

How do I serve static admin files in Django 1.4?

I have a Django project that was started with Django 1.2. Now I'm trying to run it under Django 1.4, in a development environment, using the built-in webserver. One thing I cannot get working is the static files for the admin interface. In my django server's window, I see:
Django version 1.4, using settings 'settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
[18/Jul/2012 11:38:04] "GET /admin/ HTTP/1.1" 200 6452
[18/Jul/2012 11:38:05] "GET /admin/admin/css/base.css HTTP/1.1" 404 4249
[18/Jul/2012 11:38:05] "GET /admin/admin/css/dashboard.css HTTP/1.1" 404 4264
I see that ADMIN_MEDIA_PREFIX has been deprecated, but I'm clearly missing the HOWTO that tells me what I have to do to get the admin pages working in development.
Have you tried running collectstatic to gather your static files?
https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#collectstatic
I finally started another project with "django-admin startproject", and started picking through the settings file. I found that the new settings file had:
added 'django.contrib.staticfiles' to INSTALLED_APPS
added a few STATIC_ settings. I copied these four:
STATIC_ROOT = ''
STATIC_URL = '/static/'
STATICFILES_DIRS = ()
STATICFILES_FINDERS = ()
And now things appear to be working.
In django 1.4 you can use the static tag
{% load static %}
<a href="{% static 'img/foo.png' %}">

How to use django-compressor with apache?

I'm been using Django Compressor to manage my coffee/less files and its great for development, but I've had some issues to make it work for my production deployment.
My idea is to have apache to host the static files, possibly in another server. I'm setting COMPRESS_OFFLINE = True on the settings.py file.
Then I do the following
python manage.py compress - This populates the CACHE directory in my static directory, where all static files will be collected.
python manage.py collectstatic - This collects static files from all the apps on my project (some of which don't use compressor) into my static directory.
Copy the static directory somewhere to be hosted with apache. And setup apache to serve the files.
Modify the static_url variable in the settings.py file to point to the static server.
If I open any page, I get the following error on my server, this only seems to happen when I have DEBUG = False and COMPRESS_OFFLINE = True on my settings.py file:
TemplateSyntaxError: Caught OfflineGenerationError while rendering:
You have offline compression enabled but key
"777ba26736d046ab043dc151e7e9a060" is missing from offline manifest.
You may need to run "python manage.py compress".
When I check the static/CACHE directory, I confirm what the error says, this is my manifest.json file:
{
"6189b8598993d1cbdbd35d4dfd1a6711": "<script type=\"text/javascript\" src=\"http://192.168.1.123/CACHE/js/2f6ca6616bd6.js\"></script>",
"5c66dbed0e5b766c6e32773cd8585f3c": "<link rel=\"stylesheet\" href=\"http://192.168.1.123/CACHE/css/154d95903951.css\" type=\"text/css\" />"
}
If I delete the CACHE directory and rerun python manage.py compress, I get a new set of ID's both on the error message and the manifest file, but the ID on the error is still missing on the manifest.
So, I guess there are two questions here. Why is it not working? What is the proper way to achieve this?
Thanks.
If you've run compress, and you still get the message
OfflineGenerationError: You have offline compression enabled but key "4971a40e3b459a8cda8287a7f7caa96d" is missing from offline manifest. You may need to run "python manage.py compress"
then it's likely you have dynamic content inside compress tags. Make sure that compress is always the innermost block, and that there are no tags inside the compress block.
I guess you're using django-compressor 1.1.2 which doesn't support static template tag {% static "..." %}.
Try installing the dev version of django-compressor with:
pip install django_compressor==dev
It should solve the problem.
David Wolfe is absolutely right: had to dig throught all the code of mine to get rid of {% trans... etc.
I make it like this:
<script>
window.__enter_email = "{% trans "Enter correct email" %}"
window.__url = "{% url "shop:go" %}"
</script>
{% compress js %}
<script>
$("#bla")..... window.__enter_email ...
</script>
{% endcompress %}
Hope, helps someone!