Search code examples
djangodjango-templatesdjango-viewsdjango-imagekit

django-imagekit - better way of showing a default image?


I'm using django-imagekit to resize my user avatars and right now to display a default avatar (if the user didn't upload his/her avatar) I do this:

views.py

    try:
        usr_avatar = UsrAvatar.objects.get(user=request.user.id)        
    except UsrAvatar.DoesNotExist: 
        usr_avatar = UsrAvatar.objects.get(id='0')  

template.html

<img src="{{ usr_avatar.avatar_image.url }}" >

This works fine but every time a user didn't upload his/her avatar I'm hitting the database for the default avatar image.

Is there a way to eliminate hitting the database when the user doesn't have an avatar image loaded by somehow attributing the default image link to usr_avatar or just doing something in the template.html? Thank you!


Solution

  • Apt username given your question!

    You could create a context processor that provides the default avatar to every template and simply make sure that the context processor caches the image

    settings.py

    TEMPLATE_CONTEXT_PROCESSORS = (
    ...
    'myapp.context_processors.default_avatar',
    ...
    )
    

    myapp/context_processors.py

    from django.core.cache import cache 
    def default_avatar(request):
        default_avatar = cache.get('default_avatar', False)
        if not default_avatar:
            default_avatar = UsrAvatar.object.get(id='0')
        return {
            'default_avatar' : default_avatar
        }
    

    Now the template variable 'default_avatar' is available in every template:

    {% if usr_avatar %}
        {{ usr_avatar }}
    {% else %}
        {{ default_avatar }}
    {% endif %}
    

    Alternatively just use the cache in your original query:

    try:
        usr_avatar = UsrAvatar.objects.get(user=request.user.id)        
    except UsrAvatar.DoesNotExist: 
        usr_avatar = cache.get('default_avatar', False)
        if not usr_avatar:
            usr_avatar = UsrAvatar.objects.get(id='0')  
    

    But Finally, it might be even better to avoid keeping the default avatar in the database at all and instead just write a context processor like above but instead of getting the default avatar from the DB, just have a static url to the image

    from django.conf import settings
    def default_avatar(request):
        return {
            'default_avatar' : '%simages/default_avatar.jpg' % settings.STATIC_URL
        }