Django role based views?

2019-01-16 02:25发布

I'm looking for some input on how others would architect this. I'm going to provide class (django group) based views.

For example, a user's group will determine what views/templates he or she will have access to. I'm thinking of perhaps storing paths to view functions in a table to determine what a user's link bar will consist of. Filter specifications can also be stored to determine what rows will fill these templates.

A good example is a hospital nursing units. Nurses at one unit need not see the entire hospital's patients. They only need to see their patients. Doctors on the same unit need only to see those patients as well, but they should have access to much greater functionality.

Has this been done via some third party application? And how would you approach this problem?

Thanks, Pete

9条回答
甜甜的少女心
2楼-- · 2019-01-16 03:23

We had a similar problem. Django's groups aren't REALLY suited to this, but you can shoehorn them in.

The way we did it was as follows:

Every access-controlled object has a ManyToMany relation to the groups table. Each group was used to define a specific type of permission ("can view patient basics", "can edit patient contact info", and so on). Users are added to the groups that they should have permissions for (in your example of seeing only patients in this hospital, you could have a "valley-view-hospital" group).

Then when you go to display a list of records to a user, you filter based on the conjunction of the two groups. A user has to have all the associated group permissions to view a given object.

If your system requires it, you can keep a separate ManyToMany of negative permissions, or separate read/write permissions. You could also define a set of meta-groups (doctor, nurse) that result in your lookup filter retrieving the actual subset of permissions.

As far as your link-bar problem goes, you can generate those programatically using the same system - filter based on the classes of objects the user can see or edit, and then use a get_absolute_url() type function (maybe call it get_index_url()) to return the links for the index of each class of object.

Because all this is fairly complex, you'll probably end up wanting to do some level of caching for these things, but get it working before you bother optimizing. It is possible, and it's less ugly in code than it is in words.

查看更多
时光不老,我们不散
3楼-- · 2019-01-16 03:25

On a site for an expert on Pinot Noir wine we created per-object access based on a number of different criteria. If the inbound link had a referer field that matched the domain name of a featured winery, then the user got a 'winery token' which expanded to all articles, tasting notes, etc. related to that winery. We use 'named tokens' for give aways at tasting events and they gave access to specific parts of the site. We even use this to grant certain types of permissions to search engine spiders and then make sure that links that come from those search engines have the same permissions as the spider did (ie. no cloaking games).

The short version is that you can create a class (we called them TokenBuckets which hold Tokens) and each object (on a detail page, or a list page, or whatever) can ask the user's TokenBucket if a certain level of access is allowed.

Basically it's a weird kind of ACL system. It wasn't that hard to create the mechanics. All of the magic is in determining under what circumstances which tokens go into the bucket.

查看更多
啃猪蹄的小仙女
4楼-- · 2019-01-16 03:27

There is a new very interesting project about role based permissions in Django: http://bitbucket.org/nabucosound/django-rbac

查看更多
登录 后发表回答