I'm trying to give the user the ability to upload images on a website I created with Django and the images are uploaded fine when running with DEBIG=True but the issue is that when DEBUG=False the image files doesn't upload to the MEDIA_ROOT instead it gets uploaded to STATIC_DIRS. Also, even the files that are already in MEDIA_ROOT after executing python manage.py collectstatic aren't loaded to the template and the image URL gives the 404 Page Not Found error.
The CSS and JS files are still served so it means only the media url
isn't working.
Following are the codes I'm using.
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('Home.urls')),
path('account/', include('Account.urls')),
]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage'
Note that I'm using whitenoise as the storage backend.
Here is the model code that is used to upload the file.
#deconstructible
class PathAndRename(object):
def __init__(self, sub_path):
self.path = sub_path
def __call__(self, instance, filename):
ext = filename.split('.')[-1]
filename = '{}.{}'.format(uuid4().hex, ext)
return os.path.join(self.path, filename)
rename_pp = PathAndRename('img/profile-pictures')
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True)
avatar = models.ImageField(upload_to=rename_pp, blank=True, null=True, default='img/profile-pictures/default-profile-pic.png')
def save(self, *args, **kwargs):
super(Profile, self).save(*args, **kwargs)
image = Image.open(self.avatar.path)
if image.width > 100 or image.height > 100:
output_size = (100, 100)
image.thumbnail(output_size, Image.ANTIALIAS)
image.save(self.avatar.path, file_quality=100)
When using DEBUG=True it means that you are at development side thus your local machine is able to serve the files (media files) but with DEBUG=False it is taken like you are now on deployment side.
To serve media files from that, you need to have a bucket(like amazon S3) which will store those files and will get served from there.
So if your media files are working fine when DEBUG=True, that means it is fine.
Now all you need is a place to store them.
I've used this instead of your STATICFILES_STORAGE and when debug=False everything works fine.
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'
Related
I have being using django for sometime but recently noticed this. Before now I thought images in django, by default, gets uploaded in the
path specified in STATIC_URL but I just saw that the bahaviour is diffrent in my app. I have this set up in settings.py:
class BlogPost(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)
category = models.CharField(max_length=50, choices=Categories.choices, default=Categories.medications)
title = models.CharField(max_length=50)
slug = models.SlugField()
image = ResizedImageField(upload_to='images/blog/', null=True, blank=True)
introduction = models.CharField(max_length=255)
body = models.TextField()
settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static',),
os.path.join(BASE_DIR, 'frontend/build/static'),
]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
The static, staticfiles, and media are within the root directory. In my django app, if media directory isn't present the
images get uploaded in static directory. However, when both static and media directorie are present preference is given to the media
directory (the images get uploaded in media directory). Did I make a mistake somewhere?
STATIC_ROOT was used to store all kinds of files like JavaScript, CSS and media files. Bot now the MEDIA_ROOT is used explicit for images and other media. That's where all you medias should go, you can also create additional directories in MEDIA_ROOT ex. for each model you have.
More about MEDIA_ROOT here
I have some default images in my media folder in Djang. However, on my website, I cannot see the images being displayed and I get a 404 error.
Now my project folder tree is(project name is register):
register
-- live-static
---- static-root
---- media-root
------ defaults
and my media and static files settings are:
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
STATIC_ROOT = os.path.join(BASE_DIR, 'live-static', 'static-root')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'live-static', 'media-root')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage'
And inside my urls.py in the same folder as wsgi.py I have:
urlpatterns = [
"""
My other urls
"""
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT ) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
My static files are loaded and the server can retrieve them, however, the images that I added to my folders in media-root are returning a 404 error by the server. Why is this happening as I have already also set STATICFILES_STORAGE as well?
This is something I got hung up on with my first Heroku deploy. Since Heroku projects run on dynos, they eventually go to sleep if there is not a request within a certain period of time. When the dyno restarts, it does not save the uploaded data. Here is a link to some information from Heroku: https://help.heroku.com/K1PPS2WM/why-are-my-file-uploads-missing-deleted
What I ended up doing is setting up an Amazon S3 bucket for storage of these files. Dennis Ivy did a video explaining how to do this: https://youtu.be/inQyZ7zFMHM
Update your setting file like this
there is no need to change any thing else
in urls.py change the urlpatterns to. remove STATIC_ROOT etc
+static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
in setting.py like this. remove other file settings like STATICFILES_STORAGE
MEDIA_URL = '/media/'
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static')
]
#if your media folder is in public_html which contain the media file
MEDIA_ROOT = '/home/yourusername/public_html/media'
STATIC_ROOT = '/home/yourusername/public_html/static'
#if your media folder is in other_folder which contain the media file
MEDIA_ROOT = '/home/yourusername/other_folder /media'
STATIC_ROOT = '/home/yourusername/other_folder /static'
I am running python 3.7/Django==2.2.6 . My issue is all old files uploaded through django admin console were accessible from media folder when i go with domain.com/media/. But when i upload a new file, it says successfully saved and i can see the file in media folder but when access it it says 404 not found. All old files in media folder still accessbile.
My settings.py
DEBUG = 'True'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
urls.py
urlpatterns = [
path(......),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Try this:
class HomeSliderModel(models.Model):
image = models.FileField(null=False, blank=False, upload_to = '/user_directory_path/')
is_active =models.BooleanField(null=False, blank=False, default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-updated']
def __str__(self):
return self.image.name
I need to Display the static file, I follow Django document but it is not displayed.
1.In Models file
image = models.ImageField(upload_to='images/')
2.In urls.py file
from django.conf import settings
from django.conf.urls.static import static
...
+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
3.In settings.py file
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'lost_items/static/')
]
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
finally, I run this command
python manage.py collectstatic
when I GET API, the image in this URL
"image": "http://localhost:8000/media/images/n73.jpg"
So, When I click on it, I get the page not found, and:
The current path, media/images/money.jpg, didn't match any of these.
I assume that the images was uploaded by the user.
add this to your urls.py
if settings.DEBUG is True:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
All uploaded files or "media" will have the Media URL. It only makes sense that Media URL must be added to urls.py
I have a django app (installed on a Debian server) where there is file upload.
Traditionaly, it ulpload in a folder in site_media.
For some reason,(please don't ask why,take it for granted) I have to save the files in a different disk.
The path to the other disk is /disk/site_media
The saving do the other disk is donw succesfully!
When I try to open the file by clicking on it , I get File not Found.
I am open to ideas!!!
Here's my code when uploading the file:
obj = form.save(commit=False)
obj.user_id = self.request.user.pk
obj.save()
initial_path = obj.file.path
print(initial_path)
new = settings.MEDIA_ROOT_NEW + obj.file.name
print(new)
#os.rename(initial_path,new)
shutil.move(initial_path, new)
I upload the files in my EmployeeDoc class:
class EmployeeDoc(models.Model):
file = models.FileField('DocFile', upload_to='edocs/')
employee = models.ForeignKey(Employee , related_name='documents')
user = models.ForeignKey(User , related_name='employeedocs')
created_at = models.DateTimeField(auto_now_add=True,default=timezone.now)
update_at = models.DateTimeField(auto_now=True,default=timezone.now)
I get the files in my template with a function written under my Employee class:
class Employee(models.Model):
name ...
last ...
def getDocuments(self):
return EmployeeDoc.objects.filter(employee_id=self.pk,del_f=0)
Here are my paths in settings.py:
MEDIA_ROOT = os.path.join(PROJECT_PATH, 'site_media/')
MEDIA_ROOT_NEW = '/disk/site_media/'
MEDIA_URL = '/site_media/'
In my urls.py despite all the othe urls I have:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
You're serving MEDIA_ROOT directory on MEDIA_URL url. That means files from MEDIA_ROOT_NEW won't be accessible on MEDIA_URL url.
If you want to serve all your media files from MEDIA_ROOT_NEW, change line:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
to
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT_NEW)
If you want to serve both directories on one URL, consider using nginx or other web server for that.