Simple Django Tip #9
How to provide a default image for your Profile picture?

Search for a command to run...
How to provide a default image for your Profile picture?

No comments yet. Be the first to comment.
In this series, I write about my journey of building WorkBuddy (previously named it Wobu), a work journal. I will share my learning, dos & donts, tips & tricks, best practices and more.
Send email using MailerSend
Some thoughts on why I built WorkBuddy, from someone who hasn't written here in a while

From content personalization to lead capture: the automation patterns that solve real business problems

See how three powerful tools work together to create professional user onboarding flows

Build scalable update systems that handle calculations, validations, and complex business logic

A step-by-step guide to updating data seamlessly by integrating Xano's backend with WeWeb's front-end

Image attribute: Social media illustrations by Storyset
I started to write about Django tips in concurrence to my development with a product I'm building. As and when I complete developing a logical step, I take the crux of it and share it in a post. As I wanted to share my progress in public, I thought this would be an aspect to it πββοΈ.
In my previous post on Django tips, we looked at how to conditionally navigate post successful login. In this post, let's look at different ways to provide a default image to your profile picture aka avatar. I chose this one as it's common practice for every single User model to have a placeholder for a profile picture.
For the sake of the post, let's define a CustomUser model like so π
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
display_name = models.CharField(max_length=20, \
null=True, blank=True)
first_name = models.CharField(max_length=150, \
validators=[validators.validate_aplhabets_only],\
null=True, blank=True)
last_name = models.CharField(max_length=150,
validators=[validators.validate_aplhabets_only], \
null=True, blank=True)
avatar = models.ImageField(<< will be expplained below >>)
contact_number = models.CharField(max_length=25, null=True, blank=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
# denotes whether the user clicked on activation/confirmation link
is_account_verified = models.BooleanField(default=False)
# denotes the date when the user joined the platform
date_added = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = []
objects = CustomUserManager()
def __str__(self):
return f"{self.email}"
The column avatar is the one that is of interest. There are multiple ways to handle it and let's look at a couple of them.
Default Image while defining the Model
We can provide a default path to the user's avatar. Just make sure to load the image in the mentioned folder. Usually it will resemble one of the images shown in this link.
avatar = models.ImageField(upload_to="avatars/", null=True, blank=True, default='path/to/default/avatar.jpg')
This is one of the most straight forward method to handle a default image.
Default Image while accessing the image in the Template
If we do not want a default image in the Model as modifying something in the model will lead to migrations and it's better not to keep changing details in a Django Model. An alternate approach will be to handle it directly in the template itself.
If the user's avatar column has a value, then that is used, else the default image.
{% if user.avatar %}
<img src="{{ user.avatar.url }}" alt="User avatar">
{% else %}
<img src="{% static 'path/to/default/avatar.jpg' %}" alt="Default avatar">
{% endif %}
Note the usage of {% static %} template tag in case of default image.
π‘ Do not forget to {% load static %}
Using a Helper function in the Model definition class
A third approach is to use a helper function in the Model class of CustomUser. This function will return the avatar url if it has been set else the path to the default. βIn my opinion, this is a much cleaner approach as all things CustomUser is within the Model itself without altering any aspect at a column definition.
class CustomUser(AbstractBaseUser, PermissionsMixin):
# ...
def get_avatar_url(self):
if self.avatar and hasattr(self.avatar, 'url'):
return self.avatar.url
else:
return 'path/to/default/avatar.jpg'
We then access the function directly in the template like so π
<img src="{{ user.get_avatar_url }}" alt="User avatar">
Using a templatetag
In case your project has a lot of image fields with a need for default, then consider using templatetags.
templatetags in near future πCreate a folder in your django project and name it templatetags. Create all your custom tags under this folder. For our avatar, let's create a file and name it image_tags.py.
As a first step, create an instance for template.Library(). Write a simple function that returns the default image if the user's avatar is not set, else return the set avatar url.
from django import template
register = template.Library()
@register.simple_tag
def get_avatar_url(user):
return user.avatar.url if user.avatar else 'path/to/default/avatar.jpg'
In your template, you can make use of the newly created custom tag like so π
{% load image_tags %}
<img src="{% get_avatar_url user %}" alt="User avatar">
This is a short post that talks about four different approaches when you need to show an image by default for an ImageField in Django. Factors to keep in mind while choosing in approach can be:
Is it an one off case?
Are there a lot of image fields?
Not many developers are going to touch the code base
Size of the Django project
Hope you liked this post and don't forget to share the approach that you usually take π