I have put an ImageField on my Django model, and with the pre-existent profiles it works (the image upload), but I can't delete the image from the admin panel and I can't create a new user.
The thrown error is:
ValueError at /admin/custom_user/customuser/1/
The 'avatar' attribute has no file associated with it.
Request Method: POST
Request URL: http://localhost:8000/admin/custom_user/customuser/1/
Django Version: 1.8
Exception Type: ValueError
Exception Value: The 'avatar' attribute has no file associated with it.
Exception Location: /home/stefano/projects/blog-project/blogprojectenv/local/lib/python2.7/site-packages/django/db/models/fields/files.py in _require_file, line 46
Python Executable: /home/stefano/projects/blog-project/blogprojectenv/bin/python
Python Version: 2.7.6
Python Path:
['/home/stefano/projects/blog-project',
'/home/stefano/projects/blog-project/blogprojectenv/lib/python2.7',
'/home/stefano/projects/blog-project/blogprojectenv/lib/python2.7/plat-x86_64-linux-gnu',
'/home/stefano/projects/blog-project/blogprojectenv/lib/python2.7/lib-tk',
'/home/stefano/projects/blog-project/blogprojectenv/lib/python2.7/lib-old',
'/home/stefano/projects/blog-project/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/blog-project/blogprojectenv/local/lib/python2.7/site-packages'] Server time: Thu, 24 Mar 2016 13:12:38 +0000
This is the model
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)
I've tried to put null=True and blank=True on the model, but the error is still there. I've tried to put required=False on "init" method in forms.py
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
Still there.
What can be done?
EDIT: Here's the complete traceback
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.
I think that a condition asking if self.avatar
before opening the avatar image could work because if there is not an avatar there is not reason to delete it, from my point of view. Something like this:
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)
I hope this can help you to find the solution. Thanks :)