5

ユーザーがデータベースに対してカスタム クエリを作成するためのインターフェイスを提供しようとしています。許可されているレコードのみをクエリできるようにする必要があります。そのために、 django-guardianを使用して行ベースのアクセス制御を適用することにしました。

これが私のスキーマの外観です

class BaseClass(models.Model):
    somefield = models.TextField()
    class Meta:
        permissions = (
            ('view_record', 'View record'),
        )

class ClassA(BaseClass):
    # some other fields here
    classb = models.ForeignKey(ClassB)

class ClassB(BaseClass):
    # some fields here
    classc = models.ForeignKey(ClassC)

class ClassC(BaseClass):
    # some fields here

次のようにget_objects_for_groupを使用できるようにしたいと思います。

>>> group = Group.objects.create('some group')
>>> class_c = ClassC.objects.create('ClassC')
>>> class_b = ClassB.objects.create('ClassB', classc=class_c)
>>> class_a = ClassA.objects.create('ClassA', classb=class_b)
>>> assign_perm('view_record', group, class_c)
>>> assign_perm('view_record', group, class_b)
>>> assign_perm('view_record', group, class_a)
>>> get_objects_for_group(group, 'view_record')

これにより、QuerySet が得られます。上記で定義した BaseClass を使用して、他の関連クラスに対して生のクエリを作成できますか?

>>> qs.intersection(get_objects_for_group(group, 'view_record'), \
                    BaseClass.objects.raw('select * from table_a a'
                                          'join table_b b on a.id=b.table_a_id '
                                          'join table_c c on b.id=c.table_b_id '
                                          'where some conditions here'))

このアプローチは理にかなっていますか?この問題に取り組むためのより良い方法はありますか?

ありがとう!

編集:

この問題に対処する別の方法は、ユーザーごとに個別のテーブルを作成することです。これによりアプリケーションが複雑になる可能性があることは理解していますが、

  • ユーザー数は長期的には 100 人を超えることはありません。消費者向けアプリケーションではありません。
  • 私たちのユースケースによると、これらのテーブル全体でクエリを実行する必要がある可能性はほとんどありません。同じモデルに属する table1、table2、table3 から何かを集計する必要があるクエリは記述しません。
  • 顧客ごとに個別のテーブルを維持することには利点があります。

これは実行可能なアプローチだと思いますか?

4

3 に答える 3

2

何をする必要があるかはもうお分かりだと思います。あなたが探している言葉はマルチテナンシーです。それは顧客ごとに1つのテーブルではありませんが。お客様に最適なのは、顧客ごとに 1 つのスキーマです。残念ながら、マルチテナンシーに関する最高の記事はもう入手できません。キャッシュされたバージョンが見つかるかどうかを確認してください: https://msdn.microsoft.com/en-us/library/aa479086.aspxそれ以外の場合は、インターネット上で多数の記事を入手できます。

もう 1 つの実行可能なアプローチは、カスタム マネージャーを調べることです。Model-Customer ごとに 1 つのカスタム マネージャーを作成し、それに応じてクエリを実行できます。しかし、これらすべてがアプリケーションの複雑さにつながり、すぐに手に負えなくなります。アプリケーション セキュリティ レイヤーにバグがあると、悪夢のようなものです。

あなたが編集で言ったように、両方を比較検討すると、マルチテナンシーソリューションが断然最良のアプローチであると言えます。

于 2017-11-28T12:15:26.273 に答える