【问题标题】:django-fsm: Permissions not raising exceptiondjango-fsm:权限不引发异常
【发布时间】:2017-11-19 20:43:39
【问题描述】:

我有基于源和目标规则的转换装饰器在django-fsm(有限状态机)中运行良好。现在我正在尝试添加权限处理。这看起来很简单,但似乎无论我做什么,都会执行转换,而不管用户的权限或缺乏权限。根据文档,我已尝试使用 Django 权限字符串,并且已尝试使用 lambda。我已经尝试了所有这些:

@transition(field=state, source='prog', target='appr', permission='claims.change_claim')

和

@transition(field=state, source='prog', target='appr', permission=lambda instance, user: not user.has_perm('claims.change_claim'),)

并且,作为一个双重检查,因为permission 应该响应任何返回 True/False 的可调用对象,只需:

@transition(field=state, source='prog', target='appr', permission=False)
def approve(self):

应该在访问转换时为所有用户提出TransitionNotAllowed。但是不行 - 即使没有权限的基本用户仍然可以执行转换 (claim.approve())。

为了证明我的权限字符串是正确的:

print(has_transition_perm(claim.approve, request.user))

打印 False。我正在做如下验证(适用于源/目标):

class ClaimEditForm(forms.ModelForm):
    '''
    Some users can transition claims through allowable states
    '''

    def clean_state(self):
        state = self.cleaned_data['state']
        if state == 'appr':
            try:
                self.instance.approve()
            except TransitionNotAllowed:
                raise forms.ValidationError("Claim could not be approved")
        return state

    class Meta:
        model = Claim
        fields = (
            'state',
        )

视图处理程序是标准的:

if request.method == "POST":
    claim_edit_form = ClaimEditForm(request.POST, instance=claim)
    if claim_edit_form.is_valid():  # Validate transition rules

我错过了什么?谢谢。

【问题讨论】:

    标签: django django-fsm


    【解决方案1】:

    问题是permission 属性的验证方式与源/目标验证器不同。您必须评估在代码中其他地方的装饰器中建立的权限,而不是装饰器引发错误。因此,要从表单执行权限验证,您需要传入用户对象,在表单的init 中接收用户,然后与has_transition_perm 的结果进行比较。所以这行得通:

    # model
    @transition(field=state, source='prog', target='appr', permission='claims.change_claim')
    def approve(self):
    ....
    
    # view
    if request.method == "POST":
        claim_edit_form = ClaimEditForm(request.user, request.POST, instance=claim)
            ....
    
    # form
    from django_fsm import has_transition_perm
    
    class ClaimEditForm(forms.ModelForm):
        '''
        Some users can transition claims through allowable states
        (see permission property on claim.approve() decorator)
        '''
    
        def __init__(self, user, *args, **kwargs):
            # We need to pass the user into the form to validate permissions
            self.user = user
            super(ClaimEditForm, self).__init__(*args, **kwargs)
    
        def clean_state(self):
            state = self.cleaned_data['state']
            if state == 'appr':
                if not has_transition_perm(self.instance.approve, self.user):
                    raise forms.ValidationError("You do not have permission for this transition")
    

    【讨论】:

      猜你喜欢
      • 2020-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-24
      • 2014-10-14
      • 2014-10-27
      相关资源
      最近更新 更多