每家餐厅都有多位经理。
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失败,因为我得到了重定向。如果我尝试通过浏览器访问URL,也会发生这种情况。重定向进入登录过程,就好像用户没有访问视图的权限一样。
我的代码出了什么问题?
答案 0 :(得分:3)
我正在玩django-rules以确定它是否适合项目的需要并遇到你在django-rules上添加的问题。
在测试中添加pdb跟踪并完成设置后,我注意到以下内容:
第二个链接是一个赋值,覆盖先前赋值中设置的身份验证后端。
通过将'rules.permissions.ObjectPermissionBackend'
添加到第二组后端,测试通过时没有错误。
我在github上发出拉取请求来解决这个问题:https://github.com/tavolia/Tavolia/pull/5
干杯!