Using Django “rules” with CBVs doesn't seem to

2019-07-22 12:39发布

Each restaurant can have multiple managers.

class Restaurant(models.Model):
    ...
    managers = models.ManyToManyField(User, related_name='restaurants_which_they_manage')

Only restaurant managers can change a restaurant listing. I'm using django-rules to enforce this. I've got a predicate that creates a nice verbose "is_restaurant_manager" reference :

@rules.predicate
def is_restaurant_manager(user, restaurant):
    return user in restaurant.managers.all()

And here is the permission :

rules.add_perm('restaurants.change_restaurant', is_restaurant_manager)

Finally, here is my view :

class RestaurantChange(PermissionRequiredMixin, UpdateView):
    model = Restaurant
    permission_required = 'restaurants.change_restaurant'
    fields = ['name', 'description', ]

I've got two tests.

Test A checks that the permission works properly :

self.assertEqual(rules.has_perm('restaurants.change_restaurant', self.user, self.restaurant), True)

This first test passes successfully.

Test B attempts to access the url with a valid user :

url = reverse('restaurants__restaurant_change', kwargs={'pk': self.restaurant.key,})
response = self.client.get(url)
self.assertEqual(response.status_code, 200)

Test B fails, as I get a redirection. This also happens if I try to access the url via the browser. The redirection goes to the login process, as though the user didn't have permission to access the view.

What's wrong with my code ?

1条回答
够拽才男人
2楼-- · 2019-07-22 13:00

I was playing around with django-rules to see if it suits the needs of a project and run into the issue you added on django-rules.

After adding a pdb trace in the tests and going through your settings I noticed the following:

https://github.com/tavolia/Tavolia/blob/7aca6530a8a301b8b81999095cf7535c363dd484/_project/settings.py#L121-L124

https://github.com/tavolia/Tavolia/blob/7aca6530a8a301b8b81999095cf7535c363dd484/_project/settings.py#L142-L145

The second link is an assignment, overriding authentication backend set in the previous assignments.

By adding the 'rules.permissions.ObjectPermissionBackend' to the second set of backends, the tests pass without error.

code diff and test run

I made a pull request on github to solve this issue: https://github.com/tavolia/Tavolia/pull/5

Cheers!

查看更多
登录 后发表回答