在我的用户模型中,我有一个ImageField
,其中包含一个upload_to
属性,该属性将根据用户的ID动态创建图像路径。
avatar = models.ImageField(storage=OverwriteStorage(), upload_to=create_user_image_path)
def create_user_image_path(instance, image_name):
image_name = str(instance.user.id) + image_name[-4:]
return 'users/{0}/avatars/{1}'.format(instance.user.id, image_name)
注册后,出现如下错误:
系统找不到指定的路径: 'C:\ Users \ xx \ PycharmProjects \ project_name \ media \ users \ 150 \ avatars'
如果我删除了ID和头像,只添加了图像名称(没有新目录),它将成功工作并写入图像。我曾尝试在此目录上执行chmod -R 777
,但它仍然不能动态创建这些新目录。我不确定自己在做什么错。
编辑
class OverwriteStorage(FileSystemStorage):
def get_available_name(self, name, *args, **kwargs):
# Delete all avatars in directory before adding new avatar.
# (Sometimes we have different extension names, so we can't delete by name
file_path = os.path.dirname(name)
shutil.rmtree(os.path.join(settings.MEDIA_ROOT, file_path))
return name
我看到的问题是由于我的OverwriteStorage
函数。当我删除它时,它保存。我该如何修复此功能,以使其覆盖(如果存在)?
答案 0 :(得分:0)
我认为您的问题instance.user.id
我建议您尝试如下导入用户,这可能会有帮助
from django.contrib.auth.models import User user = User.objects.get(id=user_id) def create_user_image_path(instance, image_name): image_name = str(user) + image_name[-4:] return 'users/{0}/avatars/{1}'.format(user.id, image_name)
但是django向用户AUTH_USER_MODEL
推荐
实施
from django.contrib.auth import get_user_model User = get_user_model()
当您查看替代存储时,变量name
将获取您要上传的图像的名称。您的file_path = os.path.dirname(name)
返回的是带有图片名称的文件夹。当shutil.rmtree绑定以查找文件夹时,它返回错误,找不到路径。使用条件语句,即if
或try except block
,如下所示。
from django.core.files.storage import FileSystemStorage from django.conf import settings from django.core.files.storage import default_storage import os class OverwriteStorage(FileSystemStorage): def get_available_name(self, name, max_length=None): """Returns a filename that's free on the target storage system, and available for new content to be written to. Found at http://djangosnippets.org/snippets/976/ This file storage solves overwrite on upload problem. Another proposed solution was to override the save method on the model like so (from https://code.djangoproject.com/ticket/11663): def save(self, *args, **kwargs): try: this = MyModelName.objects.get(id=self.id) if this.MyImageFieldName != self.MyImageFieldName: this.MyImageFieldName.delete() except: pass super(MyModelName, self).save(*args, **kwargs) """ # If the filename already exists, remove it as if it was a true file system if self.exists(name): os.remove(os.path.join(settings.MEDIA_ROOT, name)) # default_storage.delete(os.path.join(settings.MEDIA_ROOT, name)) return name
像您这样
class OverwriteStorage(FileSystemStorage): def get_available_name(self, name, *args, **kwargs): # Delete all avatars in directory before adding new avatar. # (Sometimes we have different extension names, so we can't delete by name if self.exists(name): file_path = os.path.dirname(name) shutil.rmtree(os.path.join(settings.MEDIA_ROOT, file_path)) return name