'getattr(): attribute name must be string' error in admin panel for a model with an ImageField

Question:

I have the following model set up:

class UserProfile(models.Model):
    "Additional attributes for users."
    url = models.URLField()
    location = models.CharField(max_length=100)
    user = models.ForeignKey(User, unique=True)
    avatar = models.ImageField(upload_to='/home/something/www/avatars', height_field=80, width_field=80)

    def __unicode__(self):
        return "Profile of " + self.user.username

It’s supposed to store additional information about a user, for example an avatar.

Unfortunately, when I try to upload an image via the admin panel, it gives me an error, something like:

getattr(): attribute name must be string

Which is not produced when I remove that field from the model, do a db reset and reload the server. I’d imagine the cause is this particular field, just not sure how.

This is my traceback:

File "/usr/lib/pymodules/python2.6/django/core/handlers/base.py" in get_response
  92.                 response = callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/pymodules/python2.6/django/contrib/admin/options.py" in wrapper
  226.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/usr/lib/pymodules/python2.6/django/views/decorators/cache.py" in _wrapped_view_func
  44.         response = view_func(request, *args, **kwargs)
File "/usr/lib/pymodules/python2.6/django/contrib/admin/sites.py" in inner
  186.             return view(request, *args, **kwargs)
File "/usr/lib/pymodules/python2.6/django/db/transaction.py" in _commit_on_success
  240.                 res = func(*args, **kw)
File "/usr/lib/pymodules/python2.6/django/contrib/admin/options.py" in add_view
  718.                 new_object = self.save_form(request, form, change=False)
File "/usr/lib/pymodules/python2.6/django/contrib/admin/options.py" in save_form
  551.         return form.save(commit=False)
File "/usr/lib/pymodules/python2.6/django/forms/models.py" in save
  407.                              fail_message, commit, exclude=self._meta.exclude)
File "/usr/lib/pymodules/python2.6/django/forms/models.py" in save_instance
  65.         f.save_form_data(instance, cleaned_data[f.name])
File "/usr/lib/pymodules/python2.6/django/db/models/fields/files.py" in save_form_data
  283.             setattr(instance, self.name, data)
File "/usr/lib/pymodules/python2.6/django/db/models/fields/files.py" in __set__
  316.             self.field.update_dimension_fields(instance, force=True)
File "/usr/lib/pymodules/python2.6/django/db/models/fields/files.py" in update_dimension_fields
  368.             (self.width_field and not getattr(instance, self.width_field))

Exception Type: TypeError at /admin/proj/userprofile/add/
Exception Value: getattr(): attribute name must be string
Asked By: cwj

||

Answers:

The problem is probably this:

height_field=80, width_field=80

height_field and width_field, if you use them, are supposed to be names of fields on the model which contain the height and width information. Fix this it should work.

Answered By: Daniel Roseman

Your problem is with height_field=80 and width_field=80 these should not contain the height and width you require but rather the names of fields in your model that can have the values for height and width save in them.

As explained in the Django documentation for the ImagedField these are attributes on your model which will be populated for you when the model is saved. If you want this information populated for you the create model attribute where this information can be stored otherwise just remove these attributes they are optional.

Answered By: Tendayi Mawushe

Basically the

width_field and height_field

is used by django to refer to the model-field that is will be used to store the value of the width and height of the image.

try this instead;

class UserProfile(models.Model):
    "Additional attributes for users."
    url = models.URLField()
    location = models.CharField(max_length=100)
    user = models.ForeignKey(User, unique=True)
    avatar = models.ImageField(upload_to='/home/something/www/avatars', height_field="img_height", width_field="img_height")
    img_width = models.PositiveIntegerField()
    img_height = models.PositiveIntegerField()

    def __str__(self):
        return "Profile of " + self.user.username
Answered By: escobar619