在CBV中使用Django“规则”似乎无效

问题描述:

每家餐厅都可以有多个管理员。在CBV中使用Django“规则”似乎无效

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

只有餐厅经理才能更改餐厅列表。我正在使用django-rules来执行此操作。我有一个创建了一个很好详细 “is_restaurant_manager” 参考谓词:

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

这里是权限:

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

最后,这里是我的观点:

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

我有两个测试。

测试A检查的权限正常工作:

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

这第一个测试成功通过。

测试B尝试使用有效的用户访问的网址:

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

测试B失败,因为我得到了重定向。如果我尝试通过浏览器访问网址,也会发生这种情况。重定向转到登录过程,就好像用户没有权限访问视图。

我的代码有什么问题?

+0

如何设置用户并在测试中分配权限? – Alasdair

+0

Hello Alasdair,我使用'User.objects.create_user',然后'Restaurant.objects.create',后面跟着'restaurant.managers.add(user)'。 我不认为问题来自测试,因为我可以在浏览器中重现它。 – Brachamul

+0

如何在测试中登录用户? – Alasdair

我在玩django-rules,看它是否适合项目的需求,并遇到你在django-rules上添加的问题。

在测试中加入了PDB跟踪,并通过设置去后,我注意到以下几点:

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

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

第二个环节是赋值,覆盖认证后端在前面的设置分配。

通过将'rules.permissions.ObjectPermissionBackend'添加到第二组后端,测试通过时没有错误。

code diff and test run

我做了GitHub上拉的请求来解决这个问题:https://github.com/tavolia/Tavolia/pull/5

干杯!

+0

令人惊叹!谢谢 ! – Brachamul