Django user_passes_test()
可以访问视图参数吗?
例如,我有一个视图,它接收id
来检索特定记录:
def property(request, id):
property = Property.objects.get(id=int(id))
该记录有一个名为user_id的字段,其中包含最初创建记录的用户的ID。我希望用户只能查看自己的记录,否则会被重定向。
我想使用看似简单干净的自定义装饰器。
对于自定义装饰器是否有一些类似的东西可以工作?
@user_passes_test(request.user.id = Property.objects.get(id=int(id)).id, login_url='/index/')
def property(request, id):
property = Property.objects.get(id=int(id))
我尝试创建名为test_func
的单独user_is_property_owner
来包含将当前用户与属性记录user_id进行比较的逻辑
@user_passes_test(user_is_property_owner(id), login_url='/index/')
def property(request, id):
property = Property.objects.get(id=int(id))
def user_is_property_owner(property_id):
is_owner = False
try:
Property.objects.filter(id=property_id, user_id=user_id).exists()
is_owner = True
except Property.DoesNotExist:
pass
但无法将当前用户ID和请求中的属性ID转换为user_is_property_owner
装饰器功能。
编辑添加我正在使用的解决方案。我在每个视图测试中都进行了测试。很简单。我认为使用装饰器可能更漂亮,更简单。
def property(request, id):
# get object
property = Property.objects.get(id=int(id))
# test if request user is not user id on property record
if request.user.id != property.user_id:
# user is not same as property user id so redirect to index
return redirect('index')
# rest of the code if request user is user_id on property record
# eg it is ok to let user into view
答案 0 :(得分:1)
通常,(使用基于类的视图),我将在get_queryset
方法中处理此问题,因此它会像
class PropertyDetail(DetailView):
def get_queryset(self):
return self.request.user.property_set.all()
如果属性不是当前用户,那将给出404。如果您最终获得的权限关系多于Property
,则可能更喜欢使用django-guardian之类的项目。
如果您查看UserPassesTestMixin,则会在致电test_func
之前看到它处理dispatch
,因此如果您决定,您必须自己致电self.get_object(request)
走那条路。