1

既存のアプリケーションに ACL を実装する必要があります。
そこで、データベースにusergroup、およびgroupmembersテーブルを追加しました。関連付けテーブルgroupmembersを介して、ユーザーグループ
の間の ManyToMany 関係を定義しました。アプリの一部のリソース (つまりitem ) を保護するために、追加の関連付けテーブルauth_itemsを追加しました。これは、グループ/ユーザーと特定のitemの間の ManyToMany 関係の関連付けテーブルとして使用する必要があります。

項目には次の列があります:

  • user_id --> ユーザー テーブル
  • group_id --> グループ テーブル
  • item_id --> アイテムテーブル

少なくともuser_id列とgroup_id列が設定されています。そのため、特定のアイテムへのグループまたはユーザーのアクセスを定義することができます。

AssociationProxy を使用して、ユーザー/グループとアイテムの間の関係を定義しました。

ユーザーがアクセスできるすべてのアイテムを表示したいのですが、それを行うのに本当に苦労しています。次の基準が使用されます。

  • ユーザーが所有するすべてのアイテムを表示する必要があります (item.owner_id = user.id)
  • すべての公開アイテムを表示する必要があります (item.access = public)
  • ユーザーがアクセスできるすべてのアイテムを表示する必要があります (auth_item.user_id = user.id)
  • ユーザーのグループがアクセスできるすべてのアイテムが表示されます。

最初の 3 つの基準は非常に単純ですが、4 番目の基準を実行するのは非常に困難です。

これが私のアプローチです:

clause = and_(item.access == 'public')
if user is not None:
   clause = or_(clause,item.owner == user,item.users.contains(user),item.groups.contains(group for group in user.groups))

3 番目の基準ではエラーが発生します。

item.groups.contains(group for group in user.groups)

これが良いアプローチであるかどうかは、実際にはわかりません。
多対多の関係をフィルタリングする際の最良のアプローチは何ですか?
別のリスト/関係に基づいて多対多の関係をフィルタリングするにはどうすればよいですか?

ところで、私は最新の sqlalchemy (6.0) と elixir バージョンを使用しています

洞察をありがとう。

4

1 に答える 1

1

contains()方法は単品チェック用です。グループテーブルがGroupクラスにマップされていると仮定して、次を試してください。

item.groups.any(Group.id.in_([group.id for group in user.groups])
于 2010-06-03T12:09:32.633 に答える