0

I use django-cms for a project and in the frontend (template) I want to select a random image from a folder.

The media is managed by django-filer. I know how to use the files when I assign them directly in my models, but I can't figure out if and how it is possible to select a random image.

For a better understanding, I have a model where I can choose an image. If that is not set by the editor, I want to choose a random image as backup.

thomas
  • 1,446
  • 8
  • 20
  • Is the random image referenced in the DB ? – Nab Ilovich Sep 13 '17 at 07:23
  • I don't know to be honest, I'm relatively new to django.What I can say is, that I created the folder in filer and I uploaded all images with it. Since I can edit the meta data for the images in filer, I guess there has to be some sort of reference in the DB. – thomas Sep 13 '17 at 07:26

2 Answers2

0

In your settings add the path to the media folder where the images are loaded. e.g.

RANDOM_IMAGES = '%s/fallback_images/' % MEDIA_ROOT

Then you can create a template tag that simply list the images in the media folder and take one randomly.

Your tag could be something like this:

import random
import os
from django import template
from django.conf import settings

register = template.Library()

@register.simple_tag
def random_image():
    list_images = os.listdir(path=settings.RANDOM_IMAGES)
    return random.choice(list_images)

Now in your template then you can use something like this

{% if mymodel.image %}
  ... do something with the image provided by the model
{% else %}
  use the tag `random_image`
{% endif %}

Not sure but you can achieve the same using default

{{ mymodel.image|default:random_image }}

Have a look at the docs about the templates tag and how to build them: https://docs.djangoproject.com/en/1.11/howto/custom-template-tags/

Karim N Gorjux
  • 2,880
  • 22
  • 29
  • Maybe it's a problem with my setup but the folder I created via filer is not present in the MEDIA_ROOT folder. The files are organised in a folder structure that seems to be based on hashes. So, this does not work unfortunately. – thomas Sep 13 '17 at 08:15
  • 1
    You are right, but you can get the folder from the database. Have a look at the source code here: https://github.com/divio/django-filer/blob/develop/filer/models/foldermodels.py – Karim N Gorjux Sep 13 '17 at 10:14
  • 1
    Thank you! That helped and I solved my problem. I will post that asap. – thomas Sep 13 '17 at 10:40
0

To solve this I had to use the Folder model of the filer. This is my model:

class HeroExtension(TitleExtension):

    image = FilerImageField(
        blank=True,
        null=True
    )

    def get_hero_image(self):
        if self.image:
            return self.image

        folder = Folder.objects.filter(name='Heros')
        if folder:
            file = random.choice(folder.first().files)
            if file:
                return file

        return None

First I return the image of the model, if it is set. if not, I look for the specific folder and select a random image from that.

If nothing is found, I return None in any other case an image will be returned.

My template looks like this:

{% if request.current_page.get_title_obj.heroextension.get_hero_image %}
{% with hero_image=request.current_page.get_title_obj.heroextension.get_hero_image %}
<img class="hero__image"
     alt="{{ hero_image.default_alt_text }}"
     srcset="{{ hero_image|thumbnail_url:'hero-450' }} 800w,
             {{ hero_image|thumbnail_url:'hero-576' }} 1024w,
             {{ hero_image|thumbnail_url:'hero-768' }} 1360w,
             {{ hero_image|thumbnail_url:'hero-1080' }} 1920w"
     sizes="100vw"
     src="{{ hero_image|thumbnail_url:'hero-1080' }}">
{% endwith %}
{% endif %}
thomas
  • 1,446
  • 8
  • 20