在Django中尝试删除图像或创建新用户时,ImageField上出现ValueError



我在Django模型上放了一个ImageField,使用预先存在的配置文件(图像上传),但我无法从管理面板中删除图像,也无法创建新用户
抛出的错误为:

值错误,位于/admin/custom_user/customuser/1/
"avatar"属性没有与其关联的文件。
请求方式:POST
请求URL:http://localhost:8000/admin/custom_user/customuser/1/
Django版本:1.8
异常类型:ValueError
异常值:"avatar"属性没有与其关联的文件。
异常位置:/home/stefano/projects/blogprojectenv/local/lib/python2.7/site-packages/django/db/models/fields/files.py,在_require_file中,第46行
Python可执行文件:/home/stefano/projects/blogprojectenv/bin/Python
Python版本:2.7.6
Python路径:
['/home/stefano/projects/blog-project',
'/home/stefano/projects/blogproject/blogprojectenv/lib/python2.7',
'/home/stefano/projects/blogproject/blogprojectenv/lib/python2.7/plat-x86_64-linux-gnu',
'/home/stefano/projects/blogproject/blogprojectenv/lib/python2.7/lib-tk',
'/home/stefano/projects/blogproject/blogprojectenv/lib/python2.7/lib-old',
'/home/stefano/projects/blogproject/blogprojectenv/lib/python2.7/lib-dynload',
'/usr/lib/python2.7',
"/usr/lib/python2.7/plat-x86_64-linux-gnu",
'/usr/lib/python2.7/lib-tk',
'/home/stefano/projects/blogproject/blogprojectenv/local/lib/python2.7/site packages']服务器时间:2016年3月24日星期四13:12:38+0000

这是型号

class CustomUser(AbstractBaseUser, PermissionsMixin):
    first_name   = models.CharField(max_length=254, blank=True)
    second_name  = models.CharField(max_length=254, blank=True)
    email        = models.EmailField(blank=True, unique=True)
    date_joined  = models.DateTimeField(_('date joined'), default=datetime.now())
    avatar       = models.ImageField('profile picture', upload_to='images/avatars/', null=True, blank=True)
    is_active    = models.BooleanField(default=True)
    is_admin     = models.BooleanField(default=False)
    is_staff     = models.BooleanField(default=False)
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'second_name']
    objects = CustomUserManager()
    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')
    def save(self, *args, **kwargs):
        pil_image_obj = Image.open(self.avatar)
        new_image = resizeimage.resize_width(pil_image_obj, 300)
        new_image_io = BytesIO()
        new_image.save(new_image_io, format='JPEG')
        temp_name = self.avatar.name
        self.avatar.delete(save=False)
        self.avatar.save(
            temp_name,
            content=ContentFile(new_image_io.getvalue()),
            save=False
        )
        super(CustomUser, self).save(*args, **kwargs)

我试着在模型上设置null=True和blank=True,但错误仍然存在。我已经尝试在forms.py 中的"init"方法上设置required=False

class CustomUserChangeForm(forms.ModelForm):
    email = forms.EmailField(label='', required=True, widget = forms.TextInput(
        attrs = {
            'placeholder': 'E-Mail',
            'class': 'form-control'
        }
    ))
    first_name = forms.CharField(label='', required=True, widget=forms.TextInput(
        attrs = {
            'placeholder': 'First name',
            'class': 'form-control'
        }
    ))
    second_name = forms.CharField(label='', required=True, widget=forms.TextInput(
        attrs = {
            'placeholder': 'Second name',
            'class': 'form-control'
        }
    ))
    avatar = forms.ImageField(label='', required=False, widget=forms.FileInput(
        attrs = {
            'class': 'form-control',
            'label': 'Profile pic'
        }
    ))
    class Meta:
        model = CustomUser
        fields = ('email', 'first_name', 'second_name', 'avatar')
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user', None)
        super(CustomUserChangeForm, self).__init__(*args, **kwargs)
        self.fields['avatar'].required = False
    def clean_email_address(self):
        email = self.cleaned_data.get('email')
        if self.user and self.user.email == email:
            return email
        if CustomUser.objects.filter(email=email).count():
            raise forms.ValidationError(u'That email address already exists.')
        return email
    def save(self, commit=True):
        user = super(CustomUserChangeForm, self).save(commit=False)
        user.email = self.cleaned_data['email']
        if commit:
            user.save()
        return user

还在那里。

能做些什么?

编辑:这是完整的回溯

Environment:

Request Method: POST
Request URL: http://localhost:8000/admin/custom_user/customuser/1/
Django Version: 1.8
Python Version: 2.7.6
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'blog',
 'custom_user',
 'django_markdown',
 'parsley')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware')

Traceback:
File "/home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/django/contrib/admin/options.py" in wrapper
  616.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  110.                     response = view_func(request, *args, **kwargs)
File "/home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  57.         response = view_func(request, *args, **kwargs)
File "/home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner
  233.             return view(request, *args, **kwargs)
File "/home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/django/contrib/admin/options.py" in change_view
  1519.         return self.changeform_view(request, object_id, form_url, extra_context)
File "/home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
  34.             return bound_func(*args, **kwargs)
File "/home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  110.                     response = view_func(request, *args, **kwargs)
File "/home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
  30.                 return func.__get__(self, type(self))(*args2, **kwargs2)
File "/home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/django/utils/decorators.py" in inner
  145.                     return func(*args, **kwargs)
File "/home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/django/contrib/admin/options.py" in changeform_view
  1467.                 self.save_model(request, new_object, form, not add)
File "/home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/django/contrib/admin/options.py" in save_model
  1078.         obj.save()
File "/home/stefano/projects/blog-project/custom_user/models.py" in save
  66.       pil_image_obj = Image.open(self.avatar)
File "/home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/PIL/Image.py" in open
  2261.         fp.seek(0)
File "/home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/django/core/files/utils.py" in <lambda>
  20.     seek = property(lambda self: self.file.seek)
File "/home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/django/db/models/fields/files.py" in _get_file
  49.         self._require_file()
File "/home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/django/db/models/fields/files.py" in _require_file
  46.             raise ValueError("The '%s' attribute has no file associated with it." % self.field.name)
Exception Type: ValueError at /admin/custom_user/customuser/1/
Exception Value: The 'avatar' attribute has no file associated with it.

我认为在打开头像图像之前询问self.avatar是否有效的条件是可行的,因为从我的角度来看,如果没有头像,就没有理由删除它。类似这样的东西:

def save(self, *args, **kwargs):
    if self.avatar:
        pil_image_obj = Image.open(self.avatar)
        new_image = resizeimage.resize_width(pil_image_obj, 300)
        new_image_io = BytesIO()
        new_image.save(new_image_io, format='JPEG')
        temp_name = self.avatar.name
        self.avatar.delete(save=False)
        self.avatar.save(
            temp_name,
            content=ContentFile(new_image_io.getvalue()),
            save=False
        )
    super(CustomUser, self).save(*args, **kwargs)

我希望这能帮助你找到解决方案。感谢:)

创建实例时,磁盘上没有存储化身文件。所以您尝试打开不存在的文件。

我知道你想在更新后删除旧文件吗?

所以您不需要重写save方法。您应该使用pre_savepost_savepost_delete方法。

pre_save上,您存储当前化身,在post_save上更新后,您应该将新实例的文件路径与旧实例进行核对。如果不同,则通过os.remove 删除

post_delete上,只需删除文件。

信号

最新更新