My goal is to have an Angular project being served from the root of my development server. The files will be completely static as far as Django is concerned, no Django template processing is needed. The angular project will then make resource calls to a Django project located at /api/ on the same development server, which will then return json results generated from a view for the Angular project to process.
I assumed it would be as easy as adding the following to my urls.py file.
url(r'^/', 'django.views.static.serve', {
'document_root':'/Users/kyle/Development/project/site/app',
}),
Or
+ static("^/$", document_root="/Users/kyle/Development/project/site/app")
To the end of the urlpatterns.
With /project/site/app being the directory with the Angularjs files.
However, both of these leave me with 404 errors.
I'm open to changing the structure of the project if a more obvious solution exists.
You need to serve both index.html and your static files on / which is done like this in Django 1.10:
from django.contrib.staticfiles.views import serve
from django.views.generic import RedirectView
urlpatterns = [
# / routes to index.html
url(r'^$', serve,
kwargs={'path': 'index.html'}),
# static files (*.css, *.js, *.jpg etc.) served on /
url(r'^(?!/static/.*)(?P<path>.*\..*)$',
RedirectView.as_view(url='/static/%(path)s')),
]
See this answer where I wrote a more complete explanation of such a configuration – especially if you want to use it for production.
It turned out that it was a combination of 2 things, as shavenwarthog said, it shouldn't have the slash. Also, it needed a regular expression to direct it to the file. The final line ended up being:
url(r'^(?P<path>.*)$', 'django.views.static.serve', {
'document_root':'/Users/kyle/Development/project/site/app',
}),
I can then access files like
http://localhost/beer.jpg
note that by default Django won't serve a directory listing. Do you still get a 404 if file /Users/kyle/Development/project/site/app/beer.jpg doesn't appear as http://localhost/beer.jpg ?
in urls.py URLs don't start with a slash; compare url(r'beer') with url(r'^/beer')
I suggest just going for the standard STATIC support. It's awkward, but lets you serve file simply during development, and switch to a 3rd party server (ie Nginx) for production:
https://docs.djangoproject.com/en/dev/howto/static-files/
Related
How can I serve a directory as the default in Django?
I build a django/react application. Got it all set up with uWSGI. Static files for both react and django working (using whitenoise for multiple static directories). But files like /favicon.ico and /manifest.json in the index.html built from react return a 404 error because they don't exist.
How can I get django to attempt to serve files in the same directory as index.html if everything else fails?
Currently I serve index.html by doing the following in Django:
In myproject/urls.py:
urlpatterns = [
path('', index, name='index'),
path('favicon.ico', favicon, name='favicon'),
...other-stuff
]
In myproject/views.py
index = never_cache(TemplateView.as_view(template_name='myproject/index.html'))
favicon = never_cache(TemplateView.as_view(template_name='myproject/favicon.ico'))
The index works, but favicon doesn't. So what about the other files that need to be served? How can I define those files (anywhere from 4-20 files) to be served by uwsgi?
favicon.ico and manifest.json should be in a static directory inside your Django project not inside the react project, because Django will serve them.
I am implementing onesingal push notification on my website by reading there documentation OneSignal WebPush notification. There they say that put the corresponding javascript on the top level domain ?
In django all files are located through the route so how i should put a js on the top domain level?
eg
https://yoursite.com/manifest.json
https://yoursite.com/OneSignalSDKWorker.js
Django does not recommend serving static files through a view. So you should use nginx or apache to do it for you. It's quite easy to setup both for serving such files.
Nginx example (not tested) -
location (OneSignalSDKWorker.js|manifest.json) {
root /path/to/files/directory;
}
If you have to do it in Django, you could add the following to your main urls.py -
from django.views.generic import TemplateView
urlpatterns = [
...
path(
"manifest.json",
TemplateView.as_view(
template_name="path/to/manifest.json",
content_type="application/json"
),
name="manifest.json",
),
path(
"OneSignalSDKWorker.js",
TemplateView.as_view(
template_name="path/to/OneSignalSDKWorker.js",
content_type="application/javascript"
),
name="OneSignalSDKWorker.js",
),
...
]
So the docs says that
Upload the files to the top-level root of your site directory. The following URLs should be publicly accessible:
If you running your server in debug mode you can add route to your public static folder(it's better to have two separate folders: for basic static, and for static such as that scripts and 500.html/404.html files). w
So you need to have two separate urlpatterns.
And in production serving static should be stored though http server(such as Nginx)
I am using mkdocs for a wiki documentation site that serves markdown tutorials and general information files created by various people. mkdocs ouputs an entirely static site in a site directory. Is there anyway to serve this site in django 1.10? I know you used to be able to do something like this:
url(r'^docs/wiki/', 'django.views.static.serve', {'document_root': base.DOCS_ROOT, 'path': 'index.html'}),
url(r'^docs/wiki/(?P<path>.*)$', 'django.views.static.serve', {'document_root': base.DOCS_ROOT}),
but that no longer works in Django 1.10 because views must be callable lists or tuples.
I would prefer to not serve this out of templates because the assets for the website in order not to split the assets mkdocs creates into the django static directory from the html files it creates that would presumably be in templates.
error given if attempted to run server:
raise TypeError('view must be a callable or a list/tuple in the case of include().')
Any simple way to do this with urls?
Django 1.10 no longer allows you to specify views as a string (e.g. 'django.views.static.serve') in your URL patterns.
The solution is to update your urls.py to include the view callable. This means that you have to import the view in your urls.py. If your URL patterns don't have names, then now is a good time to add one, because reversing with the dotted python path also no longer works.
Update your code like this :
from django.views.static import serve
from django.conf.urls import url, patterns
urlpatterns = [
url(r'^docs/wiki/',serve, {'document_root': base.DOCS_ROOT, 'path': 'index.html'},name = "wiki1"),
url(r'^docs/wiki/(?P<path>.*)$', serve, {'document_root': base.DOCS_ROOT},name = "wiki2"),
]
I have been following the official documentation to the letter, trying some of the advice for related questions on here, and just searching the web in general and I am still having no luck getting one little image to load.
I have an image called 'logo.png' and my project hierarchy looks like this:
project/
mysite/
app/
__init__.py
admin.py
models.py
urls.py
view.py
mysite/
__init__.py
settings.py
urls.py
views.py
wsgi.py
static/
logo.png
templates/
index.html
calling_image.html
Inside settings.py I have STATIC_URL = '/static/'
Inside calling_image.html I have <img src="/static/logo.png">
My template calling_image.html is called by project/mysite/app/views.py which is of course then called on by project/mysite/app/urls.py and I even tried including the following two lines (as I saw suggested a few times) at the end of my urls.py:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()
Nothing works, so what have I done wrong?
Edit: Sorry I made a type, I have STATIC_URL = '/static/' with the closing slash in my settings.py and for clarification, I am running this on my dev build with python manage.py runserver
Solved: So I ended up solving this myself. I created a directory resources within project/mysite/ and placed logo.png in there. I then set STATICFILES_DIRS = (os.path.join(BASE_DIR, "resources"),) and ran collecstatic and everything worked! Didn't need to use urlpatterns += staticfiles_urlpatterns() and whatnot.
It looks like you probably need the variable STATICFILES_DIRS defined in your settings.py and that should include the location of that static directory holding logo.png.
Django only looks for static files inside a static directory inside each app by default. If you have a static file outside of any app, it won't be picked up by collectstatic automatically.
See https://docs.djangoproject.com/en/1.8/ref/settings/#std:setting-STATICFILES_DIRS
Confusion Surrounding Staticfiles
There's always a lot of confusion around Django and Static files. I believe this confusion comes from the fact that it doesn't make any sense for Django to handle static files in production, but it seems natural to use it when learning to use Django and thus when initially developing.
The reason it doesn't make any sense for Django to serve static files is that Django is a framework for rendering dynamic responses. "Static" files are not dynamic: they don't change. Thus, it's a huge waste of resources to spin up a Python application, which calls all of the Django machinery, just to find and return a file that has no dynamic content.
Staticfiles: the job of the webserver
There is something that is really good at serving static files: webservers themselves (such as a Apache, nginx, etc.). That's what they were designed to do. The webserver can run a Python/Django application or it can just locate a file and send it back, so you typically configure a webserver by telling it something like the following (in pseudo-server-speak):
When someone accesses the path /static/ let them access the files in
the following directory: /var/www/static/.
When someone accesses the
path /, spin up this Python application that lives over here:
/var/www/django-app.
Django Static Files Tools
As a result, Django comes with some helper tools that manage static files, so that your actual server can serve them.
These tools are the following(defined in settings.py):
STATIC_URL: the URL path where your server will be serving your
static files. This is just so that when you use the static templatetag, that Django knows how to urlreverse it. In other words, it's merely a convenient way of turning {% static "..." %} into /static/....
STATIC_ROOT: the place on your server (or in the
cloud somewhere), to which Django will copy your static files, so
that your server can serve them. This copying happens when you run
collectstatic.
STATICFILES_DIRS: any extra directories Django
should look for static files whenever you run collectstatic. By
default Django only looks in each app's directory for a static
directory (just like with templates).
Static Files In Development
Okay, but that's not so helpful in development where you are probably using Django's runserver command. You don't have a server running that will server static files.
Thus, you can ask Django to please also server static files for you in just this one case, because you are developing your application and don't want to run a separate server.
There is a view that automatically should pick up and serve static files when DEBUG=True. Alternately, this is also why someone might use the following:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()
Make sure that django.contrib.staticfiles is included in your INSTALLED_APPS.
In your settings file, define STATIC_URL, for example:
STATIC_URL = 'static/'
Hopes you stored images in folder projectname/static/appname/images/image.png
Finally in your html simply add the following
<img src="appname/images/image.png" alt="My image"/>
please refer django dcumentation
I tried everything, nothing worked. In the end it turn out that image was corrupt because I opened it as bytes in Visual Code editor.
Uploaded new image and everything worked.
If I recall, you need to specify STATIC_ROOT = 'static' in settings.py and you need to have a URL to direct /static to your static files. like so.
urlpatterns += patterns('',
(r'^static/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.STATIC_ROOT, 'show_indexes': True
}),
)
This could be a bit outdated but still works for me.
Also, are you trying to get this to work on your dev site with python manage.py runserver or on a production site?
Update
Here is an example for you main urls.py file.
from django.conf.urls import patterns, include, url
urlpatterns = (
url(r'^admin/', include(admin.site.urls)),
# more urls...
)
#The following enable structural 'static' files while in development mode.
if settings.DEBUG:
urlpatterns += patterns('',
(r'^static/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.STATIC_ROOT, 'show_indexes': True
}),
)
patterns is imported near the top of your urls.py file.
This is where STATIC_ROOT comes in to play.
You may also need to run python manage.py collectstatic in order for your static files to be collected from your various apps and copied into the folder that is STATIC_ROOT.
See this answer for a much more in depth explanation :)
Here is my current method of serving robots.txt
url(r'^robots\.txt/$', TemplateView.as_view(template_name='robots.txt',
content_type='text/plain')),
I don't think that this is the best way. I think it would be better if it were just a pure
static resource and served statically. But the way my django app is structured is that the static root and all subsequent static files are located in
http://my.domain.com/static/stuff-here
Any thoughts? I'm amateur at django but
TemplateView.as_view(template_name='robots.txt',
content_type='text/plain')
looks a lot more resource consuming than just a static call to my static directory which is served on nginx.
Yes, robots.txt should not be served by Django if the file is static. Try something like this in your Nginx config file:
location /robots.txt {
alias /path/to/static/robots.txt;
}
See here for more info: https://nginx.org/en/docs/http/ngx_http_core_module.html#alias
Same thing applies to the favicon.ico file if you have one.
The equivalent code for Apache config is:
Alias /robots.txt /path/to/static/robots.txt
I know this is a late reply, I was looking for similar solution when don't have access to the web server config. So for anyone else looking for a similar solution, I found this page: http://www.techstricks.com/adding-robots-txt-to-your-django-project/
which suggests adding this to your project url.py:
from django.conf.urls import url
from django.http import HttpResponse
urlpatterns = [
#.... your project urls
url(r'^robots.txt', lambda x: HttpResponse("User-Agent: *\nDisallow:", content_type="text/plain"), name="robots_file"),
]
which I think should be slightly more efficient that using a template file, although it could make your url rules untidy if need multiple 'Disallow:' options.