permission_required decorator not working for me

前端 未结 5 1115
长情又很酷
长情又很酷 2021-02-04 18:24

I can\'t figure out why the permission required decorator isn\'t working. I would like to allow access to a view only for staff members. I have tried

@permission         


        
相关标签:
5条回答
  • 2021-02-04 18:38

    By the way, if you're using class-based views, you should wrap your decorator in the method_decorator decorator (go figure):

    class MyView(DetailView):
        ...
        @method_decorator(permission_required('polls.can_vote', login_url=reverse_lazy('my_login')))
        def dispatch(self, request, *args, **kwargs):
            .... blah ....
    
    class MyModel(models.Model):
        ...
        def has_perm(self perm, obj=None):
            if perm == 'polls.canvote':
                return self.can_vote()
    
    0 讨论(0)
  • 2021-02-04 18:39

    permission_required() must be passed a permission name, not a Python expression in a string. Try this instead:

    from contrib.auth.decorators import user_passes_test
    def staff_required(login_url=None):
        return user_passes_test(lambda u: u.is_staff, login_url=login_url)
    
    @staff_required(login_url="../admin")
    def series_info(request)
    ...
    

    Thanks. That does work. Do you have an example of how to use permission_required? From the documentation docs.djangoproject.com/en/1.0/… and djangobook.com/en/2.0/chapter14 I thought what I had should work.

    Re-read the links you posted; permission_required() will test if a user has been granted a particular permission. It does not test the attributes of the user object.

    From http://www.djangobook.com/en/2.0/chapter14/:

    def vote(request):
        if request.user.is_authenticated() and request.user.has_perm('polls.can_vote'):
            # vote here
        else:
            return HttpResponse("You can't vote in this poll.")
    
       #
       #
     # # #
      ###
       #
    
    def user_can_vote(user):
        return user.is_authenticated() and user.has_perm("polls.can_vote")
    
    @user_passes_test(user_can_vote, login_url="/login/")
    def vote(request):
        # vote here
    
       #
       #
     # # #
      ###
       #
    
    from django.contrib.auth.decorators import permission_required
    
    @permission_required('polls.can_vote', login_url="/login/")
    def vote(request):
        # vote here
    
    0 讨论(0)
  • 2021-02-04 18:42

    Here is an example of behavior I don't understand. I create a user, request and decorate a test function with permission_required checking for 'is_staff'. If the user is superuser, then access is granted to the test function. If the user only has is_staff = True, access is not granted.

    from django.http import HttpRequest
    from django.contrib.auth.models import User
    from django.contrib.auth.decorators import permission_required
    
    @permission_required('is_staff')
    def test(dummy='dummy'):
        print 'In test'
    
    mb_user = User.objects.create_user('mitch', 'mb@home.com', 'mbpassword')
    mb_user.is_staff = True
    
    req = HttpRequest()
    req.user = mb_user
    
    test(req) # access to test denied - redirected
    
    req.user.is_staff = False
    
    test(req) # same as when is_staff is True
    
    req.user.is_superuser = True
    test(req) # access to test allowed
    
    0 讨论(0)
  • 2021-02-04 18:43

    This works for me on my 'project' table/model:

    @permission_required('myApp.add_project')
    def create(request):
        # python code etc...
    

    Obviously change the add_project to the add_[whatever your model/table is]. To edit it would be:

    @permission_required('myApp.edit_project')

    and to delete:

    @permission_required('myApp.delete_project')

    But I found that the key thing is to make sure your auth tables are set up correctly. This is what caused me problems. Here is a MySQL SQL query I wrote to check permissions if you are using groups. This should work in most dBs:

    select usr.id as 'user id',usr.username,grp.id as 'group id',grp.name as 'group name',grpu.id as 'auth_user_groups',grpp.id as 'auth_group_permissions',perm.name,perm.codename
    from auth_user usr
    left join auth_user_groups grpu on usr.id = grpu.user_id
    left join auth_group grp on grpu.group_id = grp.id
    left join auth_group_permissions grpp on grp.id = grpp.group_id
    left join auth_permission perm on grpp.permission_id = perm.id
    order by usr.id;
    

    I found that my permissions were not set up correctly, and also watch out for the django_content_type table which must have rows for each app and table for each of add, edit, delete. So if you have a project table you should see this in django_content_type:

    id           [generated by dB]
    app_label    myApp
    model        project
    

    If you are having trouble another good idea is to enable and use the django admin app. This will show you where your problems are, and by setting up some test permissions, users and groups you can then examine the tables discussed above to see what is being inserted where. This will give you a good idea of how auth permissions works.

    I write this to maybe save someone from having to spend a few hours figuring out what I did!

    0 讨论(0)
  • 2021-02-04 18:49

    This is how I would do it:

    from django.contrib.admin.views.decorators import staff_member_required
    
    @staff_member_required
    def series_info(request):
        ...
    

    The documentation says about staff_member_required:

    Decorator for views that checks that the user is logged in and is a staff member, displaying the login page if necessary.

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