Deploy a Django Site with another folder for static files - django

My enviroment is with Django 1.10.7, PostgreSQL 9.4 and Nginx 1.6 with Gunicorn
I have a global folder called static for common static files to use in sub apps, then i set another folder for production mode with the name 'static_root':
in my settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static_root')
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static")
]
in my urls.py:
from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
urlpatterns += (static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT))
urlpatterns += (static(settings.STATIC_URL, document_root=settings.STATIC_ROOT))
when debug is true all work perfect, but in production mode the site not see the static files
i set the location in nginx configuration too
thank!

i found the answer to my question,
the problem was that i set in the nginx configuration: root
location /static {
root /var/projects/project/static_root;
}
the correct way is: alias
location /static {
alias /var/projects/project/static_root;
}

Related

Django STATIC_URL with full domain breaks static assets locally

When working locally on a Django project that uses static files and the default static files backend, I am running into an issue when I want to get full absolute urls to the static files instead of only the path.
My settings:
DEBUG = True
BASE_DIR = Path(__file__).resolve().parent.parent
INSTALLED_APPS = ["django.contrib.staticfiles", ...]
STATIC_ROOT = BASE_DIR / "static_root"
STATIC_URL = "/static/"
MEDIA_ROOT = BASE_DIR / "media_root"
MEDIA_URL = "/media/"
STATICFILES_DIRS = (BASE_DIR / "static",)
STATICFILES_FINDERS = (
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
)
Everything works, the admin's CSS is loaded, images work, etc. But when I get the path of a file with this code:
from django.contrib.staticfiles.storage import staticfiles_storage
static_path = staticfiles_storage.url("path_to_folder/some_file.jpg")
That result is a relative path: /static/path_to_folder/some_file.jpg. This is a problem when these urls are used from my external frontend: it now has to prepend the backend's base url to all static assets. But if I'd want to deploy the static assets to S3 for example, in production, then I should not prepend these paths with the domain of the backend.
So what I tried to do was to change the STATIC_URL setting to http://localhost:8000/static/. That way the full url is passed to the frontend, but I could really easily change this setting in the backend in production.
And this is where the problem rears its head: when I change STATIC_URL to http://localhost:8000/static/, none of my static files work anymore, I just get a 404. The admin page also is completely unstyled because of this.
So, to make a long story short: how can I use an absolute STATIC_URL in local development mode with DEBUG=True?
I have created a reproduction repro: https://github.com/kevinrenskers/django-problem-repro.
Found the solution here: https://docs.djangoproject.com/en/4.1/ref/contrib/staticfiles/#django.contrib.staticfiles.views.serve.
Simply add this to the end of urls.py:
from django.conf import settings
from django.contrib.staticfiles import views
from django.urls import re_path
if settings.DEBUG:
urlpatterns += [
re_path(r'^static/(?P<path>.*)$', views.serve),
]
Then the static files will work again even with an absolute URL as the STATIC_URL setting.

Django. not able to access staticfiles in local development

I am trying serve static files in my local development (on same server I serve my site). I have run ./manage.py collectstatic with the following configs:
settings.py
STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles/')
template.html
{% load static %}
<img src="{% static 'apis/icons/random-svgrepo-com.svg' %}" style="width: 50px;">
Now I have staticfiles folder in my BASE_DIR folder, but when I try to get an image, it doesn't appear to be working expected.
http://127.0.0.1:8000/static/apis/icons/random-svgrepo-com.svg
Please help. What I am doing wrong?
First of all I think you have not configured your static files and media files. Try configuring it as follows. In your settings.py ensure to include STATICFILES_DIR, STATIC_ROOT, MEDIA_URL, MEDIA_ROOT in your settings.py and then add the below lines below STATIC_URL = 'static/':
STATIC_URL = 'static/'
MEDIA_URL = 'media/'
STATICFILES_DIRS = [BASE_DIR / 'staticfiles']
STATIC_ROOT = BASE_DIR / 'staticfiles/'
MEDIA_ROOT = BASE_DIR / 'static/media'
By doing this you are telling django where to get your static files. now your have to add the link of the static files in your project urls.py. you will add that as below.
from django.conf import settings
from django.conf.urls.static import
static
urlpatterns = [
.......
]
urlpatterns +=static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
One last thing that I assumed you had done is creating static folder in your project root and inside that static folder create media folder where all the images you want to load are. Now run python manage.py collectstatic

404 - File not found error for static files while deploying Django and Vue js integrated project in Azure web services

I created a project with Django as backend and Vue js as frontend. Initially I ran Django on one server(8000) and Vue js on another (8080) with node.js . Then, I integrated Both to the same server with proxy changes in vue.config.js. Then I ran the command NPM RUN BUILD on terminal and I moved the dist folder to Django's static folder to render. This worked perfectly in local development environment but I'm getting 404 error for static files while deploying the project in Azure web services through git-hub. Thanks for any fix or sugesstions.
Here is my settings.py file. I have also tried commenting STATIC_ROOT
STATIC_URL = '/static/'
# Vue assets directory (assetsDir)
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
Here is my vue.config.js
module.exports = {
devServer: {
proxy: {
'^/api/': {
target: 'http://127.0.0.1:8000/api/',
ws: false,
}
}
},
// outputDir must be added to Django's TEMPLATE_DIRS
outputDir: './dist/',
// assetsDir must match Django's STATIC_URL
assetsDir: 'static',
publicPath: '',
baseUrl: '',
}
Here is my project file structure
Here is the error in my console
If you are running on production server, static files are served differently from dev server. Additional changes has to be made in main urls and settings. Docs link
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# your url patterns
]
# for serving static files
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
# for serving media files (files that were uploaded through your project application)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Obviously, you have to add STATIC_URL, STATIC_ROOT, MEDIA_URL, MEDIA_ROOT in project settings.py file.
Also, you need to run python manage.py collectstatic after setting STATIC_ROOT. Docs link 1 and link 2

Django Rest Framework Routing for embedded Angular Applications

I'm trying to bundle an Angular app and deploy it as static content in a Django Rest Framework DRF application.
I don't know Django or DRF at all however, I want to take control of the routing to express something like this:
For /admin/* - delegate to built-in Django admin.
For /api/* - delegate to Django Rest Framework
For / only, and /* - treat as static content loaded from "some specified project folder", so
/ maps to file ./static/index.html
/assets/pic.jpg maps to ./static/assets/pic.jpg
I've not been able to achieve the above. All I have is this:
A template view for index.html living at ./templates/index.html - This is the from the Angular project and is not a Django template.
Other webpack bundled content copied manually to ./static such as vendor.|hash|.bundle.js
Another problem is what to do with Assets. In the angular project, HTML views refer to assets via /assets which is at the same level as index.html
I've gotten some control over paths using this command line:
ng build --deploy-url=/static --output-path=../backend/tutorial/static
The deploy-url arg results in bundled assets references in index.html being prefixed by /static which means that Django can serve them (but not favicon.ico for some reason).
The output-path arg dumps all the assets somewhere other than the default "dist" folder.
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^api/', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^', TemplateView.as_view(template_name="index.html")),
]
Url patterns looks like the above.
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static")
]
STATIC_URL = '/static/'
These are the static settings. What I need is to be able to say "/static" and "/assets" are both static asset folders.
I'm not sure what TemplateView is (urlPatterns). Maybe there's a StaticFilesView or something that maps a URL to a path on disk?
Blockquote
These are the static settings. What I need is to be able to say "/static" and "/assets" are both static asset folders.
Blockquote
You can achieve that with the following steps:
Add /assets static directory in NGINX site configuration file:
server {
....
....
# your Django project's static files - required
location /static {
alias /path/to.../static;
}
# your Angular project's static files
location /assets {
alias /path/to.../assets;
}
....
....
}
In your Django urls.py add:
from django.views.static import serve as static_serve
urlpatterns = [
....
url(r'^assets/(?P<path>.*)$', static_serve,
{'document_root':'/path/to.../assets'}),
....
....
]
That's it. You don't have to touch the static configuration in Django settings.
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(DATA_DIR, 'media')
STATIC_ROOT = os.path.join(DATA_DIR, 'static')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'reservation_exchange', 'static'),
)

Configuring Django runserver to serve static files in a non-app directory?

I'm trying to configure Django to serve static files when using runserver (production works fine). Everything works fine for all of the static files that are under an apps directory. The problem comes with static files that are not under a specific app, but are in the final static directory. For instance, I have this project structure:
/myproject/
/myproject/static/
/myproject/static/css/foo.css
/myproject/app1
/myproject/app1/static/css/bar.css
urls.py
if settings.SERVE_STATIC:
urlpatterns += patterns('',
url(r'^static/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.STATIC_ROOT}),
)
urlpatterns += staticfiles_urlpatterns() # one of these may be redundant.
settings.py
SERVE_STATIC = True
PROJECT_ROOT = '/myproject'
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static')
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(PROJECT_ROOT, 'static'),)
INSTALLED_APPS = ('app1',)
With these settings, I get the error:
ImproperlyConfigured: The STATICFILES_DIRS setting should not contain
the STATIC_ROOT setting
Which makes sense. I'm telling Django to collect static files, and put them in the same place - which could cause a loop.
If I comment out the STATICFILES_DIRS variable, django will find the static file 'bar.css'. But it does not find 'foo.css'.
If I comment out the STATIC_ROOT variable and put back the STATICFILES_DIRS, then it finds the file 'foo.css' - but of course, the 'collectstatic' command will no longer work.
Note - I realize that the '/static' directory is supposed to be empty, but the project I'm on, has files there anyway. :) As long as they're not overwritten by 'collectstatic', it looks like Django runserver should serve them - but it doesn't.
How do I serve the static files under STATIC_ROOT (such as foo.css) when running Django runserver?
Move the files that are in /static/ right now to a different directory -- call it /project-static/, for instance.
Then only include this line in urls.py:
urlpatterns += staticfiles_urlpatterns()
(remove the django.views.static.serve view)
And in settings.py, use this:
STATICFILES_DIRS = (os.path.join(PROJECT_ROOT, 'project-static'),)
Then you can put files in /project-static/ directory on your filesystem, the development server will serve them out of the /static/ URL prefix, and in production, collectstatic will find them and put them into the /static/ directory where the web server can find them.