Django-フォームの外部キーで作成者以外の項目を選択できないようにする

結論:view.pyからform.pyにrequest.userを引き渡して、querysetを指定する

【状況】業務アプリ等でレコードの作成者以外はそのレコードを外部参照しないことが良くある。
例)自分が申請した稟議のみを経費精算に回す
一般的なブログサイト(CMS)でも、複数の記事作成者がいる場合、自分の作成した記事以外は選択できないなど、動的に外部キーを選択するフィールドが存在するフォームを作成することがある。 ネットで検索してもあまり出てこず、2パターンを検討した
①行レベルで制限をかける
https://qiita.com/okoppe8/items/dbbf363ec2b1329f1bf7
②limit_choices_to
https://torina.top/detail/276/
どちらもアクセスしているユーザを取得することはできない。アクセスしているユーザ=request.userはview.pyでしか取得できない。そのため、view.pyで取得したrequest.userをform.pyに受け渡せば良い。 そのためには、get_form_args関数を使う
【view.py】
class FormCreateView(CreateView):
    model = (Model)
    form_class = (Form)
    success_url = reverse_lazy("index")

    def get_form_kwargs(self, *args, **kwargs):
        form_kwargs = super().get_form_kwargs(*args, **kwargs)
        form_kwargs['user'] = self.request.user
        return form_kwargs
【form.py】
class Form(forms.ModelForm):
    (fields) = forms.ModelChoiceField(
        queryset=(Model).objects.none(),
    )

    def __init__(self, *args, **kwrgs):
        self.user = kwrgs.pop('user')
        super(JobForm, self).__init__(*args, **kwrgs)
        self.fields['(fields)'].queryset = (Model).objects.filter(user=self.user)
参考URL
Djangoは標準機能でユーザ・グループ別にモデルとその操作に対して権限をつけることが可能。ただ、業務レベルで考えると行レベル(レコード単位)に制限(アクセス権)をつけることが必要になる。 例)kintone等の業務アプリ開発ツールはGUIで設定できる
https://jp.cybozu.help/k/ja/user/app_settings/rights/record_rights.html
Djangoでも権限のアドオンがあるが、動的に、特にRequest情報から制御することは難しい。
そのため、上記のようにView.pyからユーザ情報を取得して、form.pyに引き渡した。viewとformで設定しているが、model側で制御したい。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です