Adding profile picture to django user

erip picture erip · Jan 28, 2015 · Viewed 8.8k times · Source

I'm trying to follow this post to associate a profile picture to a user in Django.

I have the following model

class MyUser(AbstractBaseUser):
    """
    Custom user class.
    """

    GENDER_CHOICES = (
        ('M', 'Male'),
        ('F', 'Female'),
    )
    email = models.EmailField('email address', unique=True, db_index=True)
    is_staff = models.BooleanField('is staff', default=False)
    first_name = models.TextField('first name', default=None, null=True)
    last_name = models.TextField('last name', default=None, null=True)
    date_of_birth = models.DateField('date of birth', null=True)
    avatar = models.ImageField('profile picture', upload_to='static/media/images/avatars/', null=True, blank=True)
    has_picture = models.BooleanField('has profile picture', default=False)
    adult = models.BooleanField('is adult', default=False)
    gender = models.CharField('gender', max_length=1, choices=GENDER_CHOICES)

    objects = MyUserManager()

    REQUIRED_FIELDS = ['date_of_birth', 'gender']

    USERNAME_FIELD = 'email'

    # Insert a lot of methods here

    def set_avatar(self):
       self.has_picture = True

I used the form from the post, but added this to my save() for the ChangeForm:

def save(self, commit=True):
    user = super(MyChangeForm, self).save(commit=False)
    if user.avatar:          # If the form includes an avatar
       user.set_avatar()     # Use this bool to check in templates
    if commit:
        user.save()
    return user

The logic behind this is to add a picture then set a bool flag to tell the template whether to display a generic "blank user" avatar if there's no picture associated with the profile and to display a thumbnail if there's an avatar attribute within the user.

From my form, neither the uploading nor the has_picture fields get set. Within admin, however, I can upload photos.

What am I doing wrong?

Answer

levi picture levi · Jan 28, 2015

It's not good idea to set a Boolean for checking whether the user has an avatar. You have two options: you can play with the empty url in your template or define a method to set user avatar in models.py

Option 1: in your template

{% if user.avatar == None %}
    <img src="DEFAULT_IMAGE" />
{% else %}
    <img src="user.avatar"/>
{% endif %}

Option 2: in your models

def set_avatar(self):
    _avatar = self.avatar
    if not _avatar:
        self.avatar="path/to/default/avatar.png"

Also, if your user never gets saved, if because you are calling save method with commit=False.