Managing User Roles in a Client Hierarchy with Multiple Client Assignments

Welcome @TheodoreAsher !

Taking a conceptual step back, fundamentally, you’re trying to answer one question in every view:

Can Person A perform Operation X on Entity N.

This is true regardless of how you structure your data.

For every view, you know who Person A is from request.user. You know what Operation X is because it’s what that view is going to do. And you should know (or be able to determine) what Entity N is. (Frequently, it’s from information in the URL, like the primary key - or it may need to derrived from other information.)

Once you can identify this information for your views, you can then implement one (or more) of the permission-related methods such as the User.has_perms or the user_passes_test functions. (There are more than just these two - you need to evaluate what is going to work best in your specific situation.) You write whatever queries and logic is necessary to answer that question “Yes” or “No”, and handle accordingly.

Couple of additional thoughts:

The easiest way that I have found to implement a Role-Based Access Control (RBAC) system in Django is to treat the Django Group model as the Role. That gives you the inherent ability to assign permissions to Group (the “Role”) such that the built-in User.has_perm method will pass for any permission assigned either directly to User or to any of the Group to which they are assigned.
And, using an appropriate naming convention to avoid conflicts, there’s nothing wrong with using the Group model for both “functionality-based groups” and “roles”. With the has_perms function being additive, the test would pass for any permission granted to either one.

Also, when creating an arbitrary hierarchical structure, I strongly suggest that you do not implement it simply as a set of “Foreign Keys to parent”. See an earlier comment of mine at
Some modelling advice - #12 by KenWhitesell along with the external links in it. Depending upon the complexity of the models involved, you may also want to separate the “hierarchical data structure” from the “business model structure”. In other words, you don’t maintain the hierarchy as columns within the business model - it’s a separate table that manages the relationships.
In other words, your business model doesn’t contain any information about its relationships with other models in this hierarchy. That information is stored in a separate model that only contains that information.