new_progger_python
new_progger_python

Reputation: 29

How to display an avatar?

I made a function that generates avatars for users when they create a profile:

users/models.py

    def random_image():
        directory = os.path.join(settings.BASE_DIR, 'media')
        files = os.listdir(directory)
        images = [file for file in files if os.path.isfile(os.path.join(directory, file))]
        rand = choice(images)
        return rand
    
    
    class Profile(models.Model):     
        user = models.OneToOneField(User, on_delete=models.CASCADE)
        avatar_new = models.ImageField (default=random_image)
    
        def __str__(self):
            return f'{self.user.username} Profile'

For changing avatar i am using django-avatar

There is a line like this (settings):

DEFAULT_URL = ("avatar/img/default.jpg")

I would like to display not a static image (default.jpg), but the result of the random function, which assigned the user an avatar. How can I make sure that the default url contains not a static image, but the result of the field avatar_new?

Tried itDEFAULT_URL = Profile.avatar_new error. Need help pls

Upvotes: 0

Views: 621

Answers (1)

Abdul Aziz Barkat
Abdul Aziz Barkat

Reputation: 21792

django-avatar has its own model for storing Avatars. You can try to add your own AVATAR_PROVIDER as they describe in their documentation.
Something like this might work:-

from avatar.models import Avatar
from django.core.files import File

class RandomAvatarProvider(object):
    
    @classmethod
    def get_avatar_url(cls, user, size):
        if not user or not user.is_authenticated:
            return
        avatar = Avatar(user=user, primary=True)
        random_image = cls.random_image()
        image_file = File(open(random_image, 'rb'))
        avatar.avatar.save(image_file.name, image_file)
        avatar.save()
        return avatar.avatar_url(size)
    
    @staticmethod
    def random_image():
        directory = os.path.join(settings.BASE_DIR, 'media')
        files = os.listdir(directory)
        images = [file for file in files if os.path.isfile(os.path.join(directory, file))]
        rand = choice(images)
        return os.path.join(directory, rand)

Also you would have to add this into your settings:-

AVATAR_PROVIDERS = (
    'avatar.providers.PrimaryAvatarProvider',
    'avatar.providers.GravatarAvatarProvider',
    'app_name.where_provider_is.RandomAvatarProvider',
)

The random avatar provider must be last while you can chose which ones you want to keep above in which order.
Given your usecase perhaps you might want to remove GravatarAvatarProvider from AVATAR_PROVIDERS as it would always return some url.
Edit: add 'avatar.providers.DefaultAvatarProvider' at the end of AVATAR_PROVIDERS and a AVATAR_DEFAULT_URL for unauthenticated users, or write some logic for them in the space where I am returning nothing.

Upvotes: 1

Related Questions