I'm working on a project that uses both django registration and django profiles. I have a form that allows users edit/create a profile, which includes uploading a photo. Everything works fine in the following situations: a profile is created or edited and no image has ever been uploaded; a profile is edited/created and an image is uploaded; once an image is uploaded, the profile can be edited as long as the image that was previously uploaded is either changed or removed... The place I run into issues is if there is an existing profile image, and the user tries to edit his/her profile without making any changes to the current image (i.e. removing or replacing it). In that situation, I get the error 'ImageFieldFile' object has no attribute 'content_type'. Any ideas as to why this is happening. I have tried variations of other answers found in stack overflow, but couldn't get any of them to work as they were stated. What I currently have is a variation of one of those with changes I made:
class UserProfileForm(ModelForm):
def __init__(self, *args, **kwargs):
super(UserProfileForm, self).__init__(*args, **kwargs)
try:
self.fields['email'].initial = self.instance.user.email
except User.DoesNotExist:
pass
email = forms.EmailField(label="Primary email", help_text='')
class Meta:
model = UserAccountProfile
exclude = ('user', 'broadcaster', 'type')
widgets = {
...
}
def save(self, *args, **kwargs):
u = self.instance.user
u.email = self.cleaned_data['email']
u.save()
profile = super(UserProfileForm, self).save(*args,**kwargs)
return profile
def clean_avatar(self):
avatar = self.cleaned_data['avatar']
if avatar:
w, h = get_image_dimensions(avatar)
max_width = max_height = 500
if w >= max_width or h >= max_height:
raise forms.ValidationError(u'Please use an image that is %s x %s pixels or less.' % (max_width, max_height))
main, sub = avatar.content_type.split('/')
if not (main == 'image' and sub in ['jpeg', 'pjpeg', 'gif', 'png']):
raise forms.ValidationError(u'Please use a JPEG, GIF or PNG image.')
if len(avatar) > (50 * 1024):
raise forms.ValidationError(u'Avatar file size may not exceed 50k.')
else:
pass
return avatar
Thanks for any help or advice.
Here is the full traceback:
Traceback:
File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "C:\Python27\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
20. return view_func(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\profiles\views.py" in edit_profile
197. if form.is_valid():
File "C:\Python27\lib\site-packages\django\forms\forms.py" in is_valid
124. return self.is_bound and not bool(self.errors)
File "C:\Python27\lib\site-packages\django\forms\forms.py" in _get_errors
115. self.full_clean()
File "C:\Python27\lib\site-packages\django\forms\forms.py" in full_clean
270. self._clean_fields()
File "C:\Python27\lib\site-packages\django\forms\forms.py" in _clean_fields
290. value = getattr(self, 'clean_%s' % name)()
File "C:\Documents and Settings\user\projects\xlftv\lftv\userprofiles\forms.py" in clean_avatar
146. main, sub = avatar.content_type.split('/')
Exception Type: AttributeError at /instructor_profiles/edit
Exception Value: 'ImageFieldFile' object has no attribute 'content_type'
So if you look at the last point in your traceback, you'll see that your error is coming from this line main, sub = avatar.content_type.split('/')
, which appears to be from your clean_avatar
method. Looks like you're trying to make sure it's an image... I have to imagine there's another way to do that.
Looks like worst case, you should be able to parse avatar.name
to check file extensions (see https://docs.djangoproject.com/en/dev/ref/files/file/#django.core.files.File)
Btw, the way to get content_type
for an instance is ContentType.get_for_model(avatar)
.