Handling media django - python

I am trying to handle the django static and media content. This is my code in settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
In urls.py
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I am uploading files and videos to my site, everything is working fine even static and media content is being displayed.
My actual doubt is-
I am actually running in development environment. In production for collecting the static content generally python manage.py collectstatic is used and then it is handled. But in development according to docs, app called django.contrib.staticfiles is used serve static files. But what about media files, how are they served actually ??
When I upload a image it is getting stored to project_name/media/app_name insted of project_name/app_name/media/app_name as static files are being accessed from path similar to latter, why are media files being stored in different manner.
Finally:
How the media files got served in development ?
How to serve media files in production ?

When I upload a image it is getting stored to project_name/media/app_name insted of project_name/app_name/media/app_name as static files are being accessed from path similar to latter, why are media files being stored in different manner.
Media files are uploaded to the MEDIA_ROOT directory. Your MEDIA_ROOT is media, so django will keep uploaded files there.
Additionally, if in the FileField or ImageField you use upload_to path, django will create required folders accordingly. For example, for something like this:
image = models.ImageField(upload_to='myapp/')
Django will create a myapp folder inside media and keep the uploaded images there.
How the media files got served in development ?
Because of this line of code:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
It tells django to serve MEDIA_ROOT directory at MEDIA_URL.
How to serve media files in production ?
Configure your webserver to serve media and static files. Django doesn't serve media and static files because it's not good at that. An actual webserver like Nginx or Apache is configured for serving static files efficiently.

Related

Error 404 serving media files in a Django app hosted on DigitalOcean

I am making a small Django app and I want to use files uploaded via Django admin panel in production
This is from my settings.py file
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
MEDIA_URL = ''
MEDIA_ROOT = BASE_DIR
I trust admin uploaded files and want to serve them easily(without Amazon S3 and similar services), so i tried to place the uploaded files with other static files
image = models.ImageField(upload_to='static/images')
After uploading an image via admin panel i run python manage.py collectstatic in the DigitalOcean console. Whenever i try to access the image i get Error 404, while all other static files(which are real static files, not uploaded via admin panel) load successfully
I did the same thing locally and there is no problem, everything loads as expected(DEBUG=True is set both locally and on DigitalOcean). Is it some security measure that doesnt let uploaded files end up in static? How can i bypass it if i trust files uploaded via admin panel?
if you're using manage.py runserver to run you website
first make sure that the media is being served in your main urls.py
urlpatterns = [
...
] + [
static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
]
then you can use runserver with --insecure to run your website with or without DEBUG=True
python manage.py runserver 0.0.0.0:80 --insecure
https://docs.djangoproject.com/en/3.2/ref/contrib/staticfiles/#cmdoption-runserver-insecure
as in the django documentation this is not the recommended way to serve your files, you should use a reverse proxy like nginx or apache
or if you really dont want to use a reverse proxy, you could give whitenoise a try
http://whitenoise.evans.io/en/stable/django.html

Django server does not serve static files for admin page

I have a Django server running with nginx and gunicorn.
All static files are served correctly, only the admin page has no css, js, etc. .
I already ran collectstatic and restarted nginx and gunicorn.
Nothing changed.
What can I do?
Make sure to mention the locations of your staticfiles_dirs in settings.py. Also remember to mention the locations of your static files in a dynamic format instead of hard coding them in your html document.And make sure to load static in base.html.
Try using this sample code in your settings.py file:
STATIC_URL = '/static/'
STATICFILES_DIRS=[
os.path.join(BASE_DIR,'templates'),
'/var/www/static/'
]
STATIC_ROOT = os.path.join(BASE_DIR, 'assets')
After this use the following command in terminal:
python manage.py collectstatic
This should create the static folder and copy all the static objects inside

Django: In deployment where stays the static files of admin?

i have a web application runing, the statics files from apps works but in /admin/ seems like doesn't have a css file. In the production the admin page works fine.
My question is where is the css file from admin page of django?
Just in case if somebody want to check, this is my configuration of static files of the web-app in deployment
STATIC_URL = '/static/'
STATIC_ROOT = '/apps_wsgi/generic_name/main/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = '/apps_wsgi/generic_name/main/media/'
You need to run the collectstatic management command. There are static files for other apps in the site-packages of your virtualenv and that command will copy/generate them into the correct static files location for your application.

What Does Django static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) Actually DO?

I am using Django 2.2. From the Django Managing static files documentation:
If you use django.contrib.staticfiles as explained above, runserver
will do this automatically when DEBUG is set to True. If you don’t
have django.contrib.staticfiles in INSTALLED_APPS, you can still
manually serve static files using the django.views.static.serve()
view.
This is not suitable for production use! For some common deployment
strategies, see Deploying static files.
For example, if your STATIC_URL is defined as /static/, you can do
this by adding the following snippet to your urls.py:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Note
This helper function works only in debug mode and only if the given
prefix is local (e.g. /static/) and not a URL (e.g.
http://static.example.com/).
Also this helper function only serves the actual STATIC_ROOT folder;
it doesn’t perform static files discovery like
django.contrib.staticfiles.
My Interpretation
static is a helper function that serves files from the STATIC_ROOT during development (is this True?)
static only works when debug = True
static only works with a local prefix like STATIC_URL = '/static/'
When DEBUG is set to True and I use and setup the staticfiles app as explained in the documentation, if I do python manage.py runserver to start the local server, the serving of static files will be handled automatically (true??)
My Questions
What EXACTLY does adding static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) to your project's urls.py DO?
Is it true that static serves static files locally from the STATIC_ROOT directory? To test this theory, after running collectstatic, I then deleted the static directories to see if the static files still load fine (from the STATIC_ROOT) and they DON'T! Why?
How can I verify that Django is loading the static files from my STATIC_ROOT location... and not the static directories in my project and apps??
Why is adding static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) to urlpatterns necessary if Django serves static files automatically (mentioned in documentation)?
Example
settings.py
DEBUG = True
...
INSTALLED_APPS = [
'django.contrib.admin',
...
'django.contrib.staticfiles',
'puppies.apps.PuppiesConfig'
]
...
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
STATIC_ROOT = 'c:/lkdsjfkljsd_cdn'
In all my templates, I'm using {% load static %}.
Then I do: python manage.py collectstatic
At this point, it doesn't seem to matter if I have the below in my urls.py or not - my static files still load BUT I don't know if they're coming from my project's static directories or my STATIC_ROOT (c:/lkdsjfkljsd_cdn):
if settings.DEBUG is True:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Lastly, if I delete those static directories in my project, all css, js and images don't work which leads me to believe that my Django project is loading static files from my project's static directories, NOT the STATIC_ROOT.
So, again, how can I tell Django to load the static files from my STATIC_ROOT location... and not the static directories in my project and apps?? OR, do I misunderstand that Django isn't supposed to load files from my STATIC_ROOT location locally?
*Edit (adding HTML image)
I think you are mixing up few things. Let me clarify.
static:
As per documentation, it provides URL pattern for serving static file. If you go to the implementation, then you will see:
return [
re_path(r'^%s(?P<path>.*)$' % re.escape(prefix.lstrip('/')), view, kwargs=kwargs),
]
What it does is, it removes forward slash from left of the prefix(ie converts /static/ to static/), and then there is a view(which is serve) who does the pulling files.
serve:
This function does the serving files. It will serve files from a document root.
runserver:
runserver command runs the django development server. If you have django.contrib.staticfiles installed in INSTALLED_APPS, then it will automatically serve static files. If you don't want to serve static, then use runserver --nostatic. collectstatic or STATIC_ROOT has no relation to this command.
collectstatic:
This command collects all static files from different STATIC_DIRS, and put them in folder which is defined by STATIC_ROOT. collectstatic is very useful in production deployment, when you are using a reverse proxy server like NGINX or Apache etc. NGINX/Apache/Varnish uses that folder (where collectstatic stored the static files) as root and serve static from it. It is not recommended to use runserver in production. You can use gunicorn/uwsgi to serve django. But gunicorn/uwsgi does not serve static files, hence using reverse proxy server to serve static files.
finally:
To answer your questions:
No you don't have to put that in your code, unless you are not adding django.contrib.staticfiles in your INSTALLED_APPS.
No
You don't need to. STATIC_ROOT is used for different purpose
It is not. But for serving MEDIA files, you can add the following pattern:
if settings.DEBUG:
urlpatterns += [
re_path(r'^media/(?P<path>.*)$', serve, {
'document_root': settings.MEDIA_ROOT,
}),
]
In production, media files should be served by reverse proxy server as well.

serving static vs media in django 1.9

To serve the static files (CSS, JS), I set the settings:
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
This means that all my static files need to be in the project root's static folder
/app1
/app2
/media
/static #They need to be stored here, all static files
/templates
urls.py
settings.py
manage.py
However, I am storing them in my app's static folder.
/app1/static/ # Storing the static files here
/app2/static/ #and here
/media/
/static/ # but not here
Still, Django is able to serve them, how is that possible?
I tried the same thing with media files; setting
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
and storing the media (images etc) files in each app's individual media dir. This time, Django did not serve the files and served them only when either I moved the files to the project root's media dir or changed the setting to MEDIA_ROOT = os.path.join(BASE_DIR, '<app_name>/media')
Why was I allowed to serve static files even when they weren't in the project root static dir but not the media files - they were only served from the root media dir.
Please read the documentation carefully - https://docs.djangoproject.com/en/1.9/ref/settings/#staticfiles-finders
It precisely states that django will search for static files in each app + the directory stated in settings.
Quoting as in the documentation -
The default will find files stored in the STATICFILES_DIRS setting (using django.contrib.staticfiles.finders.FileSystemFinder) and in a static subdirectory of each app (using django.contrib.staticfiles.finders.AppDirectoriesFinder). If multiple files with the same name are present, the first file that is found will be used.
While this is not true for media files. Django doesn't look for media files in subdirectories.

Categories

Resources