Django Media file auto-delete - django

When I upload an image through Django administrator and I delete the image file again, why does it not delete the image int the /media directory?
When I delete an image file, I want it to delete the image automatically even from the directory, not only the model instance.
My model:
class ImageForExtractText(models.Model):
image = models.FileField()
And settings:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static")
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "media")
What should I do to make it happen, when deleting the image file from Django administration? It should be deleted from both Django administration and the media directory.

Django doesn't delete the files on delete.
You can add a signal to delete the file:
from django.db.models.signals import pre_delete
from django.dispatch.dispatcher import receiver
class ImageForExtractText(models.Model):
image = models.FileField()
#receiver(pre_delete, sender=ImageForExtractText)
def delete_image(sender, instance, **kwargs):
# Pass false so FileField doesn't save the model.
if instance.image:
instance.image.delete(False)

Related

Unable to show in frontend images uploaded via Django REST framework

I'm trying to create Django REST app, however I cannot manage to allow the url of the image to be accessible.
I managed to get the upload done, however when I have the URL there is no way to access the photo from browser. I stored them in folder profile_pictures and I was thinking of loading the image from localhost:8000/profile_pictures/image_name.jpg but I'm not sure how to setup this, as I tried linking static files to the urls but nothing seems to work.
settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static")
MEDIA_URL = '/profile_pictures/'
MEDIA_ROOT = os.path.join(BASE_DIR,"profile_pictures")
urls.py
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
However, it says that the static name is not defined even tho I import it using:
from django.conf import settings
from django.conf.urls.static import static
I upload the images with Simple REST API which I only created for testing:
class UploadPictureAPI(generics.GenericAPIView):
permission_classes = (IsAuthenticated,)
def post(self, request):
x = AdditionalUser(user=request.user, profile_picture=request.data['profile_picture'])
x.save()
print(x)
return Response({"message": "uploaded"})
and I store them in a database as such:
class AdditionalUser(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
profile_picture = models.ImageField(upload_to='profile_pictures')
user_bio = models.CharField(max_length=300)
user_instagram = models.CharField(max_length=300)
They get uploaded to the DataBase and in the folder, but I cannot get access to them from the url(which I get as profile_picture.url) of the database, it says page not found

Django Admin FileFile not open from listview

in my model class i have an attribute like this one:
c_cv = models.FileField(upload_to='mysite/static/docs', max_length=254, validators=[FileExtensionValidator(['pdf']),validate_fsize], verbose_name="CV")
in my admin.py:
list_display = ('c_data', 'c_sur', 'c_name', 'c_dob', 'c_en', 'c_de', 'c_cv')
but when i open from admin my list page, if i click on my c_cv field in list i get an error because link does not start from 127.0.0.1:8000/mysite/static/docs/file.pdf but instead from 127.0.0.1:8000/admin/cv_list/...
How can i force in admin looking my c_cv field using root of domain instad actual path as prefix?
So many thanks in advance
Have you defined a URL for viewing media ? What have you set your MEDIA_URL , MEDIA_ROOT to in the settings.py ?
I have done something like this to access uploaded files:
1.In settings.py :
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
2.Defined a url which is used to serve uploaded media files :
In urls.py:
#login_required
def protected_serve(request, path, document_root=None, show_indexes=False):
return serve(request, path, document_root, show_indexes)
re_path(r'^%s(?P<path>.*)$' % settings.MEDIA_URL[1:], protected_serve, {'document_root': settings.MEDIA_ROOT}),
This way I can also stop directory indexing of the list of the files that are uploaded.You can try this

Static and Media Files in Django 1.10

I have a ImageField in my user_accounts/models.py file which i use to store the profile picture of users.It has a upload_to field which calls a function and uploads the file to a media folder in myproj/media/.. . The Image Field also has a default field which is used to set the default profile image from the static folder.
This is an entry of User Table in development server.
In The image the avatar field shows static url but when clicked it /media/ gets attached to the url before /static/ as follows:
In The image the url bar shows /media/ attached before the static url.When i manually remove the /media/ from the url the defaultProfileImage is shown.
This is my project structure
|-myproj
|-myproj
|-__init__.py
|-settings.py
|-urls.py
|-wsgi.py
|-static
|-user_accounts
|-images
|-defaultrofileImage.png
|-user_accounts
|-__init__.py
|-models.py
|-admin.py
|-tests.py
|-views.py
|-urls.py
Models.py File
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import AbstractUser
def get_upload_url(instance , filename):
return 'userProfileImages/%s/%s'%(instance.username , filename)
class User(AbstractUser):
mobileNumber = models.IntegerField(blank = True , null = True)
avatar = models.ImageField(upload_to = get_upload_url , default = '/static/user_accounts/images/defaultProfileImage.png')
def __str__(self):
return self.username
I have the following lines added in my settings.py file
AUTH_USER_MODEL = 'user_accounts.User'
STATIC_URL = '/static/'
STATICFILES_DIRS =[
os.path.join(BASE_DIR,'static'),
]
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
MEDIA_URL = '/media/'
This is my urls.py file
from django.conf.urls import url,include
from django.contrib import admin
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api-auth/', include('rest_framework.urls')),
url(r'^user/',include('user_accounts.urls')),
] + static(settings.MEDIA_URL , document_root = settings.MEDIA_ROOT)
How should i correct the url so that when i click the url in my admin panel it shows the correct url in url bar and i get to see the defaultProfileImage??
ImageField default value refers to 'MEDIA_URL', therefore you should create media folder, place your defaultProfileImage there and use default = 'defaultProfileImage.png' in the model field, as in your example it resolves the picture path as MEDIA_URL + default so you get /media/static/....
You probably could omit default= from the model field and override save method to programmatically define the path to the avatar field.
Usually, user-uploaded media files reside in the MEDIA_ROOT and static assets in STATIC_DIRS.
You can find more info here and read about FileField which is the base class of ImageField here.

Django MEDIA_ROOT, MEDIA_URL etc

This is my first time using MEDIA_ROOT/MEDIA_URL and I'm a little confused by the configuration. I have an image upload form which saves the original image plus a resized copy. I want to save both images to my MEDIA folder, but separate them. Current structure:
project/
----apps/
--------appOne/
------------static/
------------templates/
------------__init__.py
------------models.py
------------urls.py
------------views.py
--------__init__.py/
----MEDIA/
----project/
--------__init__.py
--------settings.py
--------urls.py
----manage.py
I would like to save the original uploaded image to MEDIA/ and the resized image to a folder inside the MEDIA folder, like MEDIA/media/. Right now, it's nesting 3 times:
original image goes to ---> MEDIA/media/
resized image goes to ---> MEDIA/media/media
I'm almost positive I have my settings wrong but I've been fiddling with it for too long and nothing is working. It seems every tutorial configures things differently and I'm just not sure what the preferred structure is or why my current config isn't working the way I expect.
Here is my settings.py:
MEDIA_ROOT = os.path.join(BASE_DIR,'MEDIA')
MEDIA_URL = "media/"
models.py:
from django.conf import settings
from smartfields import fields
from smartfields.dependencies import FileDependency
from smartfields.processors import ImageProcessor
class Image(models.Model):
client = models.ForeignKey(Client, null=True, blank=True)
model_pic = fields.ImageField(upload_to=settings.MEDIA_URL, dependencies=[
FileDependency(processor=ImageProcessor(
format='PNG', scale={'max_width': 500, 'max_height': 500}))
])
views.py:
def upload(request):
form = ImageUploadForm(request.POST, request.FILES)
if form.is_valid():
client = Client.objects.get(id=request.session['id'])
image = Image.objects.create(client=client, model_pic=form.cleaned_data['image'])
return redirect(reverse('cphh:gallery'))
def show_images(request):
context = {
'images': Image.objects.all().order_by('-created_at'),
'media_url': settings.MEDIA_URL,
}
return render(request,'cphh/gallery.html', context)
The triple-nested uploaded images do render properly on my template:
{% for image in images %}
<img class="gallery-image" src="{{media_url}}{{ image.model_pic }}"
{% endfor %}
As per the documentation
MEDIA_ROOT is the Absolute filesystem path to the directory that will hold user-uploaded files.
Your code that pushes the uploaded Images to the root should have settings.MEDIA_ROOT/<sub-folder> instead of settings.MEDIA_URL
MEDIA_URL on the other hand is a placeholder for the url a client should hit to access your media. This is useful when you don't want to keep your media on your local filesystem, but to an external storage like amazon s3.
Using {{MEDIA_URL}} in your templates gives you a good way of not hard-coding the eventual media location.
first of all in the settings.py MEDIA_URL must be like this:
MEDIA_URL = "/media/"
Then delete MEDIA folder. Only media folder is enough.
and also if you need thumbnails for your uploaded images you can use Django easy_thumbnails package for this

Issues with uploading images

I want to upload images and they must be store in media folder.But when I upload an image it is uploaded and its name is store in database but image is not stored in media folder (even I don't know where it stored).
settings.py is:
MEDIA_ROOT = '/home/ghrix/html/media'
MEDIA_URL = 'media'
models.py is as:
from django.conf import settings
class Upload_files(models.Model):
image =models.ImageField(upload_to='/images')
forms.py
class ProductForm(forms.Form):
image = forms.FileField()
class Meta:
model=Upload_files
I don't know where I am wrong may be I have to import something in model.So please help me...
ur MEDIA_ROOT should be
MEDIA_ROOT = 'media'