I'm working on a Django backend deployed on a server, here's my settings:
DEBUG = False
STATIC_URL = "/staticfiles/"
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
And I want to save the users' images outside the django folder, so I've created a custom FileSystemStorage in this way:
from django.core.files.storage import FileSystemStorage
key_store = FileSystemStorage(location="/home/usr/project/media/", base_url="/media")
Where I put the absolute path of ubuntu server.
def profile_picture_url(instance, *_):
return f"{instance.user.uuid}/profile.picture.png"
picture = models.FileField(
storage=key_store, default=None, upload_to=profile_picture_url
)
But it doesn't create any file inside media folder.
Any solution?
Related
I have a directory '/media/profile_image' where profile images uploaded by users are saved. In the template I built the url by using the user object
<img id="profile_image" src="{{ request.user.profile_image.url }}"></div>
# Model
def get_profile_image_filepath(self, filename):
return f'profile_image/{self.pk}/{"profile_image.png"}'
...
profile_image = models.ImageField(max_length=255, upload_to=get_profile_image_filepath, null=True, blank=True, default=get_default_profile_image())
...
which creates the correct url to the desired directory. But it doesn't show the image, why's that?
# rendered url
<img id="profile_image" src="/media/profile_image/1/profile_image.png">
settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
dir
Dealing with Django and media files on development like this :
First install pillow
pip install pillow on your activated env.
Specify the MEDIA_ROOT variable in the settings file
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/') or MEDIA_ROOT = BASE_DIR / 'media' in Django 3.
Tell Django to serve media file (in development mode)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) in the project urls.py
file.
(Optional) Specify the MEDIA_URL variable too
URL that handles the media served from MEDIA_ROOT.
Exemple :
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media' # or os.path.join(BASE_DIR, 'media/') in Django 2
And in your model, you can define a media file like this :
class Profile(models.Model):
# Others fields
photo = models.ImageField(upload_to="photos/")
Here the upload_to is used to designate the location where the images assigned to the photo attribute will be saved on the hard drive for all instances of the model. If you don't specify a value for upload_to, the images will be saved to the root of MEDIA_ROOT.
I implemented a file upload endpoint with DRF the issue is the documents do not show the absolute url of the file as shown below on the screenshot. I expect the absolute url start with http://localhost ....
Here is my django settings
STATIC_URL = '/static/'
# The folder hosting the files
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),]
## Serving the STATIC FILES
# As declared in NginX conf, it must match /src/static/
STATIC_ROOT = os.path.join(os.path.dirname(os.path.dirname(BASE_DIR)), 'static')
MEDIA_URL = '/media/'
# do the same for media files, it must match /opt/services/djangoapp/media/
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
models.py
class Document(models.Model):
"""This represents document class model."""
file = models.FileField(upload_to='documents/inspections/%Y/%m/%d')
timestamp = models.DateTimeField(auto_now_add=True)
#property
def name(self):
name = self.file.name[33:]
return name
Django doesn't provide absoluteurl for image stored in models.ImageField. But you can modify your serializer and do this with serializer.SerializerMethodField. as you didn't provide your serializer so i assume it maybe look like this:
class Document(seralizer.ModelSerializer):
file_url = serializer.SerializerMethodField()
class Meta:
model = Document
fields = ('id','name','timestamp','file_url')
def get_file_url(self, document):
request = self.context.get('request')
file_url = document.file.url
return request.build_absolute_uri(file_url)
Django rest framework, by default, builds absolute URLs for file field if you pass request in serializer context. Try to pass the request in serializer like this.
serializer = YourSerializer(<OTHER_ARGS>, context={'request': request})
You will get the absolute URL automatically.
To make things easier I used cloudinary to host my images since eventually I will store them in the cloud in production.
Therefore:
Installed required cloudinary python packages i.e cloudinary and dj3-cloudinary-storage
Added cloudinary in installed apps:
INSTALLED_APPS = [
......
'rest_framework',
'django_extensions',
'corsheaders',
'cloudinary', # Add cloudinary
'drf_yasg',
'celery',
'django_prometheus',
'debug_toolbar',
]
Changed the default file storage in settings.py and added cloudinary configs:
CLOUDINARY_STORAGE = {
'CLOUD_NAME': '*******',
'API_KEY': '*********',
'API_SECRET': '*********',
}
DEFAULT_FILE_STORAGE = 'cloudinary_storage.storage.MediaCloudinaryStorage'
Removed below don't need it anymore in root urls.py
urlpatterns+= static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
After testing an upload here are the results:
I have created model - Profile - which presents user's profile. I have one field which is models.ImageFiled and I have method to get absolute url to this image. I have server in development role, so I've exposed /media folder.
When I use full server URL it works. Is there any method to avoid put static web server address?
# Profile
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
date_of_birth = models.DateField(blank=True, null=True)
photo = models.ImageField(upload_to='users/%Y/%m/%d',blank=True)
def __str__(self):
return 'Profile for user {}'.format(self.user.username)
#property
def get_absolute_image_url(self):
return "http://127.0.0.1:8000/{0}".format(self.photo.url)
in settings.py
MEDIA_URL = 'media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media/')
You need an absolute path with a leading slash:
MEDIA_URL = '/media/'
After some digging I found the solution.
It based on two things:
1) Media url has to be inside static directory to available to display.
2) Uploaded media has to be inside static directory.
My settings.py looks like below:
STATIC_URL = '/static/'
MEDIA_URL = '/static/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, "shop", "static", "media")
A help came from here [a link] Differences between STATICFILES_DIR, STATIC_ROOT and MEDIA_ROOT
Please be informed I researched Stack Overflow and ckeditor documentation and configured accordingly.
First I install ckeditor using
pip install django-ckeditor
Then I configured my settings.py as below
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
# media
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
# Static files (CSS, JavaScript, Images)
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]
CKEDITOR_BASEPATH = "/static/ckeditor/ckeditor"
# CKEditor settings
CKEDITOR_UPLOAD_PATH = "uploads/"
CKEDITOR_JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'
# This ensures you have all toolbar icons
CKEDITOR_CONFIGS = {
'default': {
'toolbar': None,
},
}
Then I configured my urls.py (project's url) as below
url(r'^ckeditor/', include('ckeditor_uploader.urls'))
Then I ran command collect static
ckeditor statics are collected in right location defined in settings which is /static/ckeditor/ckeditor
After that I imported and used ckeditor richtextfield in my model
from django.db import models
from ckeditor.fields import RichTextField
class Post(models.Model):
post = models.RichTextField()
While makemigrations i am getting the following error
AttributeError: module 'django.db.models' has no attribute 'RichTextField'
Change from:
post = models.RichTextField()
to:
post = RichTextField()
And in CKEDITOR_BASEPATH add "/" to the end.
CKEDITOR_BASEPATH = "/static/ckeditor/ckeditor/"
I am trying to use django-photologue, I installed it and did mentioned settings.
I have a model Blog as follows:
class Blog(models.Model):
title = models.CharField(max_length=150)
thumbnail = models.ForeignKey(Photo, related_name='blogs')
I am able to add images to blog objects, however I do not see the thumbnail in my admin interface (clicking on it basically opens base.html stored in templates folder which I simply copied from example_project, this base.html is not important for me, however seeing this thumbnail could be interesting):
NOTE: I guess my MEDIA_ROOT and MDIA_URL properties are wrong, I am not sure what I should be writing there. I get
GET http://127.0.0.1:8000/photologue/photologue/photos/cache/dog_1_admin_thumbnail.jpg 404 (Not Found)
for
MEDIA_ROOT = os.path.join(BASE_DIR, 'photologue', )
MEDIA_URL = '/photologue/'
error, on my console.
My folder structure:
The thumbnails part of the question is fixed by doing following settings:
In my urls.py file I had to
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
#all urls
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
And in my settings.py file I added:
STATIC_ROOT = os.path.join(BASE_DIR, 'public', 'static')
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'public', 'media')
MEDIA_URL = '/media/'