2017-06-17 9 views
1

django-fsm(Finite State Machine)では、ソースとターゲットのルールベースの遷移デコレータがうまく動作しています。今私はアクセス許可の処理を追加しようとしています。これは簡単なようですが、ユーザーの権限や不足にかかわらず、私が何をしていても移行が実行されるようです。 Djangoの許可文字列で試してみましたが、ドキュメントごとにlambdaを試しました。 permissionは、単に、True/Falseの返却任意の呼び出し可能に応じる必要があるため、django-fsm:例外を発生させないパーミッション

@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'),) 

と、ちょうどダブルチェックとして:私はこれらのすべてを試した

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

いずれもになります。移行にアクセスするとすべてのユーザーがTransitionNotAllowedになります。ただし、権限がない基本ユーザーであっても、引き続き遷移を実行できます(claim.approve())。

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

プリント偽:私は許可文字列の権利を持っていることを証明するために

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 

私は何をしないのですか?ありがとう。

答えて

-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") 
0

実際にドキュメントを読む必要があります。

permissions documentation

+0

もちろん、私は完全に、そして完全にドキュメントを読んでいます。私の記事で説明したように、私は両方の手法をドキュメントに記述して、結果を私の投稿に示しました。私が逃したドキュメントから何かがありますか?ありがとう。 – shacker

+0

「あなたはTransitionNotAllowedを起こすべきですか?」の文章に​​間違っています。モデルメソッドにパーミッションチェックはありません。モデルメソッドは、ユーザーについても知らない。 – kmmbvnr

+0

ああ!したがって、ソース/ターゲットの検証とは異なる動作をします。はい、それは私の誤った仮定でした。これは重要な区別であり、矛盾しているので、ドキュメントはより明確になる可能性があります。私は 'has_transition_permission'文書のセクションが"あなたのコードのどこかで権限をチェックしたいのであれば... "を意味すると理解しました。その文言を "has_transition_permissionメソッドで許可を確認する必要があります"( "can"ではなく)に変更することをお勧めします。ありがとう。 – shacker

関連する問題