通过我的项目,我有用户上传个人资料图片。我将个人资料图片保存为userID.jpg。如果他们上传了新的个人资料图片,我想覆盖旧的个人资料图片,所以我不会浪费存储空间。通过浏览stackoverflow上的先前问题,我重新定义了OverwriteStorage:
class OverwriteStorage(FileSystemStorage):
def get_available_name(self, name, max_length=None):
if self.exists(name):
os.remove(os.path.join(settings.MEDIA_ROOT, name))
return name
当我上传个人资料图片时,我可以在计算机上的目录中看到图片已被成功覆盖。图像以“media / profile / userID.jpg”路径保存。但是,当我在我的网站上显示图像时,它仍然是旧图片。通过Django站点,当我打开路径时,我看到旧图片,当我尝试通过管理员更改它时,我收到以下错误:
[WinError 32] The process cannot access the file because it is being used by another process: '\media\\profile\\userID.jpg'
我想我错误地覆盖了文件而另一个实例仍然是打开的,要解决它,我需要在覆盖前正确关闭图像。我试过这样做,但没有成功。
我做了类似的事情,但我使用信号来更新和删除图像。
Firstable,我在helpers.py
中定义了图像的名称
from django.conf import settings
from datetime import datetime
def upload_to_image_post(self, filename):
"""
Stores the image in a specific path regards to date
and changes the name of the image with for the name of the post
"""
ext = filename.split('.')[-1]
current_date = datetime.now()
return '%s/posts/main/{year}/{month}/{day}/%s'.format(
year=current_date.strftime('%Y'), month=current_date.strftime('%m'),
day=current_date.strftime('%d')) % (settings.MEDIA_ROOT, filename)
所以,我在我的模型中调用了def,特别是在图像的字段中
from django.db import models
from django.utils.text import slugify
from .helpers import upload_to_image_post
class Post(models.Model):
"""
Store a simple Post entry.
"""
title = models.CharField('Title', max_length=200, help_text='Title of the post')
body = models.TextField('Body', help_text='Enter the description of the post')
slug = models.SlugField('Slug', max_length=200, db_index=True, unique=True, help_text='Title in format of URL')
image_post = models.ImageField('Image', max_length=80, blank=True, upload_to=upload_to_image_post, help_text='Main image of the post')
class Meta:
verbose_name = 'Post'
verbose_name_plural = 'Posts'
最后,我定义了信号,以便在模型中发生操作(更新或删除)之前更新或删除图像。
import os
from django.db import models
from django.dispatch import receiver
from django.db.models.signals import pre_delete, pre_save
from .models import Post
@receiver(pre_delete, sender=Post)
def post_delete(sender, instance, **kwargs):
"""
Deleting the specific image of a Post after delete it
"""
if instance.image_post:
if os.path.isfile(instance.image_post.path):
os.remove(instance.image_post.path)
@receiver(pre_save, sender=Post)
def post_update(sender, instance, **kwargs):
"""
Replacing the specific image of a Post after update
"""
if not instance.pk:
return False
if sender.objects.get(pk=instance.pk).image_post:
old_image = sender.objects.get(pk=instance.pk).image_post
new_image = instance.image_post
if not old_image == new_image:
if os.path.isfile(old_image.path):
os.remove(old_image.path)
else:
return False
我希望,这对你有帮助。
让它将旧的重命名为userID-old.jpg,然后保存userID.jpg。很快就没有人会注意到它的发生。