Search code examples
pythondjangomulti-tenantavatar

django-tenant-schemas & avatars


Multi tenant django 1.8 setup (using django-tenants schemas)

requirements.txt:

Django==1.8.16
django-allauth==0.27.0
django-tenant-schemas==1.6.4
django-avatar==3.1.0
...

Keeping the tenants as much as possible isolated, so kept only these APPs shared (note that allauth is not here, each tenant has its own auth_user table):

SHARED_APPS = (
    'tenant_schemas',  # mandatory
    'customers', 
    'django.contrib.contenttypes',
)

Serving avatars (from /media URL) is posing an issue now since the avatar URL is unaware of the tenants. Avatars are served from

/media/avatars/<user ID>/userx-pic.jpg

but to avoid clashes it should take the tenants into account. Target is to have:

/media/avatars/<tenant>/<user ID>/userx-pic.jpg

How can this be configured? I am thinking of using RedirectView (https://docs.djangoproject.com/en/1.10/ref/class-based-views/base/#redirectview)

... but the avatars also need to be stored in the correct location. So the question is twofold:

  1. How to get the avatars in the correct -tenant aware- location?
  2. How to serve them correctly?

Solution

  • You can try to save your media files to specific tenant folder by specifying upload_to on your file field and serve it as usual. For example:

    from django.contrib.auth.models import User
    from django.db import connection
    
    def get_tenant_specific_upload_folder(instance, filename):
        upload_folder = 'avatars/{0}/{1}/{2}'.format(
            connection.tenant,
            instance.user.pk,
            filename
        )
        return upload_folder
    
    class Avatar(models.Model):
        user = models.ForeignKey(User)
        file = models.FileField(upload_to=get_tenant_specific_upload_folder)
    

    p.s. for limiting avatar access only for owners take a look at this article