Django app on Azure not getting static files - django

Got my Django project on a Azure webapp, but when I call on SSH terminal:
Python manage.py collectstatic
It says 252 files copied but my static files are not visible on my templates and static folder in wwwroot its empty...Here's my wwwroot structure:
wwwroot
|---Myproject
|---manage.py
|---oryx-manifest.toml
|---hostingstart.html
|---static //With all my static files
├── myapp
│ ├── migrations
│ ├── __pycache__
│ ├── static
| | |---Images
| | | |--myimage.png
| | | |--myimage2.png
│ └── templates
And this is my settings.py:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
STATIC_URL = '/static/'
STATICFILES_DIRS = (
('myapp', os.path.join(BASE_DIR, 'myapp', 'static')),
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
Any idea why or what am I doing wrong ?, does Azure collect different ?
EDIT> When I go to my website my images don´t show...Im calling them like this on template:
{% load static %}
<img src="{% static 'Images/myimage.png' %}" /><br>
EDIT 2 /////
In wwwroot creates indeed a folder with all my statics, but when I load my template they don´t show, in wen console I get this error for myimage.png and myimage2.png :
Failed to load resource: the server responded with a status of 404 (Not Found)

Found it !!
Just had to add this: + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) to url patterns like this:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('myapp/', include('myapp.urls')),
path('admin/', admin.site.urls),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
And it did the trick, hope it helps to anyone else!!

Django does not serve static files in production mode.
The only time it serves static files is when you turn DEBUG = True which is in development mode and this is not recommended in a production setting.
Django recommends to serve static files via CND or any other webserver. However if your website is minimal and does not get high volume traffic you can serve your static files using Django whitenoise and here is how you do it.
The below solution works on python 3.7 and Django 3.2
Step 1: Install whitenoise package
pip install whitenoise
Step 2: Ensure your BASE_DIR looks like the below
BASE_DIR = Path(__file__).resolve().parent.parent
Step 3: Add these to your settings.py. If you get any errors try commenting out STATICFILES_STORAGE and check
STATIC_ROOT = BASE_DIR / 'staticfiles'
STATIC_URL = '/static/'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
Step 4: WhiteNoise middleware should be placed directly after the Django SecurityMiddleware (if you are using it) and before all other middleware
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
# ...
]
Step 5: Ensure this is how you reference static files in your templates(also check if you have {% load static %} mentioned in your template
<link rel="stylesheet" type="text/css" href="{% static 'appname/styles.css' %}">
Step 6: Run collect static
python manage.py collectstatic
Step 7: Turn DEBUG = False and run the server to verify it works.
Some additional resources to read further:
whitenoise
Django on Azure - beyond "hello world"

Few points to note:
Below line will change
STATIC_ROOT = (os.path.join(BASE_DIR, 'Myproject/static_files/'))
to
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
You are using pointing to completely different folder here. Hence always empty You need the collectstatic command to copy files to
Project > static directory
Below remove the line os.path.join(BASE_DIR, 'static/')...
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static/'), #Not Required since you already mentioned it in STATIC_URL
('myapp', os.path.join(BASE_DIR, 'myapp', 'static')),
)
Reason:
STATIC_ROOT is the folder where static files will be stored after
using manage.py collectstatic
The absolute path to the directory where collectstatic will collect
static files for deployment.
If the staticfiles contrib app is enabled (default) the collectstatic management command will collect static files into this
directory. See the howto on managing static files for more details
about usage.
STATICFILES_DIRS is the list of folders where Django will search for
additional static files aside from the static folder of each app
installed.
This setting defines the additional locations the staticfiles app will
traverse if the FileSystemFinder finder is enabled, e.g. if you use
the collectstatic or findstatic management command or use the static
file serving view.
If issue still persists check your static file directory in apache mod_wsgi config file in the server if it is configured properly.
Check this link for help on that >> https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/modwsgi/
Cheers!!!

I would recommend checking out Whitenoise for serving your static files with Django. I haven't had an issue serving them since integrating Whitenoise. Try swapping it out with your current static file finders setup.
http://whitenoise.evans.io/en/stable/django.html

Related

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

Django collected static files are not accessible by templates

I've created a django project with some apps. Initially, I just had a single app and i had static files and templates in it. As my project grew, I added some other apps to the project which they are still accessing the statics files and templates from inside the main app. I wasn't giving much care to this problem until i tried to make a simple production and used collectstatic command. Seems i can collect my static files to the STATIC_ROOT directory but i can't access them in the templates. Here is my project structure:
shop/
-myshop(main app)
--statics
--templates
-(some other apps beside main app)
-shop(directory created by project containing settings.py, manage.py)
This is my relevant settings.py configurations:
BASE_DIR = Path(__file__).resolve().parent.parent
INSTALLED_APPS = [
...
'django.contrib.staticfiles',
...
]
STATIC_URL = '/static/'
STATICFILES_DIRS = [
BASE_DIR / 'myshop/static',
]
STATIC_ROOT = BASE_DIR / 'static'
After running collectstatic django creates the static directory in root of project but when i remove or rename the myshop/static i get static files 404 in runserver.
I dont know how to check {% load static %} resulting path in runtime to put more information here. Is there any debug routine to understand what's django backend doing?
Try this
STATIC_URL = '/static/'
STATICFILES_DIRS = [
BASE_DIR / "static",
]
STATIC_ROOT = BASE_DIR.parent / "static_cdn"
$ python manage.py collectstatic This command will copy all files from your static folders into the STATIC_ROOT directory.
You must write the names of the static folder and the static root folder diffrent.
To learn more https://docs.djangoproject.com/en/3.1/howto/static-files/#configuring-static-files

404 Error for django serving static files. How to setup django to serve static files?

Settings.py file in Project directory :
I already added following :
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
-> in template
<script src="{% static "validateurl/home.js" %}"></script>
I have a directory static under project directory. home.js is under validateurl directory under static.
Referring JS File using following in template html file :
Please advise what am I missing here.
Errors below :
Here are the steps to configure your django app to serve static files for local development.
The STATIC_ROOT default is None so you have to specify that in settings. Make sure you have something like this in your settings.py This tells your webserver where to find and serve the static file mapped to a url.
import os
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
Second also specify your STATIC_URL variable as it also defaults to none. following should suffice. This will be used for setting up the urlpattern.
STATIC_URL = '/static/'
You need to have a url pattern so your server knows what url corresponds to the static files
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Specify STATICFILES_DIRS variable in settings. So that the collect static manager knows where to find statics and put them in the STATIC_ROOT. This can be an array or tuple of items to different directories. This can be empty if you have no additional directories
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'pathtohomejsdirectory/'),)
Finally, make sure you run python manage.py collectstatic
This copies all the files specified in STATICFILES_DIRS over to the /static/ (STATIC_ROOT) directory to be served by django.
On a production, you want your webserver/reverse proxy say nginx or apache to serve the files. See here django documentation here

Django website giving trouble serving static files

I am working on a multi-app website. And I have bunch of noob questions.
My dir structure looks like as below:
/var/www/html/portal
src/
manage.py
portal/
static/
admin/
css/
img/
js/
fonts/
templates/
base.html
homepage.html
venv/
Is my dir structure as per as Django standards?
Are my STATIC files settings correct?
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
Or should it be
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')
Should I collectstatic after copying all my static files such as css,js etc or I can do it before copying files in those dirs?
If I do collectstatic without mentioning STATIC_ROOT I get an exception
django.core.exceptions.ImproperlyConfigured: You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.
But when I replace STATICFILES_DIRS with the following, my .css files stop serving. What am I doing wrong?
STATIC_ROOT = os.path.join(PROJECT_DIR, 'static')
You don't need to run staticfiles when you're running a development server and DEBUG is set to True.
Static and media files can be then served directly via the web process (Docs) with adding these lines to your main urls.py:
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
As to the whole STATIC_URL, STATIC_ROOT, MEDIA_URL and MEDIA_ROOT, they're all related to how you'll serve your app in production, with a proper webserver.
What usually happens then is that the webserver (i.e. Nginx) handles serving files, not the Django app. But the Django app needs to know where are they. So:
STATIC_URL and MEDIA_URL need to be the same in your Django app settings and in your webserver config, for example with Nginx:
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
...
location /static {
alias /home/myusername/myproject/static/;
}
location /media {
alias /home/myusername/myproject/media/;
}
STATIC_ROOT MEDIA_ROOT are 100% about how you want to structure your project on the server. Assuming the above, you need to work out how to point it to /home/myusername/myproject/static/.
Example of my settings:
BASE_DIR = Path(__file__).parent.parent.parent
MEDIA_URL = '/media/'
MEDIA_ROOT = str(BASE_DIR.joinpath('media'))
STATIC_URL = '/static/'
STATIC_ROOT = str(BASE_DIR.joinpath('staticfiles'))
Media files will be directly uploaded to the MEDIA_ROOT, but notice that you need to somehow get the static files from your applications (which could be in a number of folders, a library you use can have some extra static files, Django Admin has then, etc.) to the folder that Nginx is pointed to (which should be the same as STATIC_ROOT). That's where collectstaticfiles comes in and copies all your static files to that directory.
In regards to directory structure, there are differences of opinion on how it should be set up. A quick google search can bring up some websites and discussions on Django project structures. I recommend reading some of the information to determine what is best for your and your project.
The Django documentation has a best practices page as well that is a good resource/reminder. Django Best Practices.
I mainly followed the Two Scoops of Django directory structure. The Two Scoops has helped me a lot in understanding this. My own twist looks something like this.
src/
app/
templates/
app_name/
base.html
other_pages.html
tests/
tests.py
app_files.py
static/
images/
css/
etc..
templates/
global_includes/
include_file.html
base.html
The collectstatic should not effect the serving of your static files during development. From what I have learned, collectstatic is more for when you are serving your static files during deployment from a separate server, or aws, heroku, etc. More info can be found here in the docs: Managing Static Files, staticfiles app, Deploying static files
I have learned that if my CSS files are not serving, it usually has something to do with my path. Chrome developer tools inspect element/console helps me with any path errors.
Have you added
+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
to your your main urlpattern/urls.py?
Here is more information on serving files during development: Serving static files during development.
Lastly check that your BASE_DIR is following the correct path for your project. You may have to change it.
I hope this helps.
Remember that if you have DEBUG set to 'False' it will ignore the staticfiles setting because it is expected that your webserver will be serving this directly. This caught me out a few times until I realized I hadn't updated the staticfiles folder (which I keep in a separate repository for reasons I can't remember now).
This seems to work in current django (2.2) :
from django.conf.urls.static import serve
urlpatterns += [
path(settings.STATIC_URL[1:], serve, {'document_root': settings.STATIC_ROOT })
]

Heroku Django app static files not serving (error OSError: [Errno 2])

I have developed an application in Python with Django, and I just deployed it on heroku servers.
My settings.py file has this content:
PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = 'staticfiles'
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(PROJECT_PATH, 'static'),
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
#'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
when I run this command:
heroku run python manage.py collectstatic --noinput
I get the following error:
OSError: [Errno 2] No such file or directory: '/app/nameOfApp/static'
the urls in templates to the files that were previously stored, such as CSS and javascript files which have this kind of url in the template files:
<script type="text/javascript" src="{% static "javascripts/jquery.min.js" %}" ></script>
are served properly but the new files that are uploaded through admin panels are not stored in the same place as the previous files in static folder, namely the new uploaded files should be stored in the the same folder as other static files such as CSS and javascripts,
Question:
so how should I modify the settings.py file so that it works properly?
Media Root is for Absolute filesystem path to the directory that will hold user-uploaded files.
Example: "/var/www/example.com/media/"
Media URL is for handling the media file served from Media root.
Another important not is you will need to configure these files to be served in both development and production.
by adding this line in urls.py will do the tricks
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)