Skip to content

Images

If you like to add an image for your error's page, the suggested way is implementing your custom simple_tag.

  1. Suppose to have your model MyBackground to store all your site background's image with a filer field called image.

    example/models.py
    from django.db import models
    from filer.fields.image import FilerImageField
    
    
    class MyBackground(models.Model):
        name = models.CharField(verbose_name="Background", max_length=50, null=True)
        image = FilerImageField(null=True, blank=True, on_delete=models.CASCADE)
    
  2. Upload your images with name like the error's code of the page to be able to dynamically load different images with same html file.

  3. Create your own template tags to store the image inside the context view where you want to load image

    example/templatetags/errors.py
    from django import template
    from django.core.cache import cache
    from example.models import MyBackground
    
    register = template.Library()
    
    
    @register.simple_tag(takes_context=True)
    def load_error_img(context):
        cache_key = f"site_error_{context['error_code']}_context"
        try:
            context_cache = cache.get(cache_key)
        except Exception as err:
            context_cache = None
    
        if context_cache is None:
            try:
                custom_context = (
                    MyBackground.objects.values("image__file")
                    .filter(name=context["error_code"])
                    .first()
                )
                context_cache = cache.set(
                    cache_key, custom_context["image__file"], timeout=86400
                )
                return custom_context["image__file"]
            except Exception as err:
                print(err)
    
        return context_cache or ""
    
  4. Create your own html template inside the root of your app. Assign the result of your tag load_error_img into variable error_img and use it with static filter.

    example/template/errors.html
    {% extends 'base.html' %}
    {% load static errors %}
    
    {% block content %}
    
        {% load_error_img as error_img %}
    
        <div style="background-image: url( {% static error_img %} );">
            <strong>Oops! </strong> {{ error_message }}
        </div>
    
    {% endblock content %}
    
  5. (optional) It could be useful use the MEDIA_URL setting inside template. To do it, add the context_processor:

    settings.py
    TEMPLATES = [
        {
            "BACKEND": "django.template.backends.django.DjangoTemplates",
            "DIRS": [os.path.join(PROJECT_DIR, "templates")],
            "APP_DIRS": True,
            "OPTIONS": {
                "context_processors": [
                    "django.template.context_processors.debug",
                    "django.template.context_processors.request",
                    "django.contrib.auth.context_processors.auth",
                    "django.contrib.messages.context_processors.messages",
                    "django.template.context_processors.media",
                ],
            },
        },
    ]
    
  6. (optional) And then use the MEDIA_URL tag inside template instead of static templatetags:

    example/template/errors.html
    {% extends 'base.html' %}
    {% load static errors %}
    
    {% block content %}
    
         {% load_error_img as error_img %}
    
         <div style="background-image: url( {{ MEDIA_URL }}{{ error_img }} );">
             <strong>Oops! </strong> {{ error_message }}
         </div>
    
    {% endblock content %}
    ...
    <div style="background-image: url( {{ MEDIA_URL }}{{ error_img }} );">
       <strong>Oops! </strong> {{ error_message }}
    </div>
    ...
    

Last update: 2023-08-21