'What is the best approach to attain multi-tenancy in Django?

I'm using django as an API server(using DRF) and admin dashboard with Postgres DB. The problem is I'll have multiple tenants and I want to follow a total separation of concern flow. Data from one tenant should not in any way be accessible to the other.

Example Scenario: Say I have multiple Institutes as my clients and every institute will have all of their students onboarded on my platform. No institute should be able to access other's data.

I can think of 2 approaches:

1. Extending ModelAdmin for Admin pages and for the APIs I can get the tenant associated to a particular user from the request.

In this approach, I'll have to check for the tenant of a user in every modelAdmin class and get a filtered queryset in the def get_queryset() method

    def get_queryset(self, request):
        tenant = request.user.tenant  # using related_name of foreignkey
        queryset = Course.objects.filter(tenant_id=tenant)

And have to do this similarly in the list, create, update and destroy methods of the ModelViewSet class while creating APIs

class CourseViewSet(viewsets.ModelViewSet):
    queryset = Course.objects.all()
    serializer_class = CourseSerializer
    permission_classes = (DjangoModelPermissions,)

    def list(self, request, *args, **kwargs):
        tenant = request.user.tenant
        queryset = self.filter_queryset(self.get_queryset())
        queryset = queryset.filter(tenant__id=tenant)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    def create(self, request, *args, **kwargs):
        pass

    def update(self, request, *args, **kwargs):
        pass

    def destroy(self, request, *args, **kwargs):
        pass

2. Using Row Level Security provided by Postgres

In this approach all the filtering will be done by postgres itself, but for this to work, I'll have to create a middleware that sets the (postgres) session variable, and a mechanism to enable/disable this on a model.

More about this approach can be found in the link below:

https://schinckel.net/2017/12/20/django-multitenancy-using-postgres-row-level-security/

Please suggest which approach will be better among the two above and if there's any better approach of doing this.

Note: It's a requirement to keep all the data of all the clients in the same DB in the same Schema.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source