Django role based views?

后端 未结 9 1968
既然无缘
既然无缘 2020-12-04 06:43

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

相关标签:
9条回答
  • 2020-12-04 07: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.

    0 讨论(0)
  • 2020-12-04 07:24

    We used a role base system for a similar problem. Basically users have permissions to assume different roles.

    View functions got decorated:

    def needs_capability(capability,redirect_to="/cms/"):
       def view_func_wrapper(view_func):
           def wrapped_view_func(request,*args,**kwargs):
               if not request.role._can(capability):
                  return HttpResponseRedirect(redirect_to)
               return view_func(request,*args,**kwargs)
           return wrapped_view_func
       return view_func_wrapper
    

    The rest of the magic is inside the request.role attribute which got set inside a context processor. Authenticated users got a Role, for the unwashed masses a DummyRole.

    Access to information was restricted further inside the templates:

     {% if not request.role.can.view_all_products %}
              Lots of products, yeah!
     {% endif %}
    

    Not the cleanest solution in my opinion, but worked as expected.

    0 讨论(0)
  • 2020-12-04 07:27

    You can use django user roles

    https://github.com/dabapps/django-user-roles

    0 讨论(0)
  • 2020-12-04 07:29

    I had a similar problem not too long ago. Our solution did the trick, though it might be too simple for your situation. Like everyone is suggesting, we used the django permission system to control what user interactions with models. However, we didn't just try to group users, we also grouped objects through a GenericForeignKey.

    We built a model that linked to itself to allow for hierarchies to be developed.

    class Group( models.Model ):
        name = models.CharField( ... )
        parent = models.ForeignKey( 'self', blank=True, null=True)
        content_type = models.ForeignKey( ContentType )
        object_id = models.PositiveIntegerField()
        content_object = generic.GenericForeignKey( 'content_type', 'object_id' )
        ...
    

    To make it work, we also created a model to serve as the django User model's user profile. All it contained was a ManyToManyField linked to the Group model above. This allowed us to give users access to zero or more Groups as required. (documentation)

    class UserProfile( models.Model ):
        user = models.ForeignKey( User, unique=True )
        groups = models.ManyToManyField( Group )
        ...
    

    This gave us the best of both worlds and kept us from trying to shoehorn everything into django's permission system. I'm using this basic setup to control user's access to sports content (some users can access whole leagues, some only one or two conferences, some only have access to individual teams), and it works well in that situation. It could probably be a generalized enough to fit your needs.

    0 讨论(0)
  • 2020-12-04 07:30

    This question has been asked in Oct 2009 and the problem still exists in July 2012.

    I have searched for a good Role-Based app, and found django-permission as the best result.

    Three important features that I needed were Roles, view Decorators and Templatetag; apparently django-permissions has all of them. Read it's docs for it's usage.

    The only drawback is that it's under development.

    0 讨论(0)
  • 2020-12-04 07:31

    If you don't need real per-object ACLs, then you can just use the Django permission system. To get a list of all available permissions:

    from django.contrib.auth.models import Permission
    perms = Permission.objects.all()
    

    There is an API for other authentication and authorization sources, so you do not need to stick with this permissions table.

    You may hack this Django system to fit your needs in terms of this authorization model (RBAC) or you may come up with an ACL-like solution.

    0 讨论(0)
提交回复
热议问题