12

私は現在、会社に所属する従業員がいる構造を作成しています。この会社内で、いくつかのグループを作成できる必要があります。よろしければランク付けします。低いランクには少ないアクセス許可を割り当て、高いランクには多くのアクセス許可を割り当てることができます。

オブジェクト レベルのアクセス許可を取得したいのですが、django-guardian プロジェクトが必要なものを正確に提供してくれることに気付きました。これはネイティブの User および Group オブジェクトで動作するため、会社のオブジェクトにネイティブのグループ オブジェクトを実装する方法を見つけようとしています。

私が直面している問題は、グループ内の名前が一意であることです。そのため、2 社が同じグループを追加すると、エラーが発生します。

ある意味で機能する実装を見つけましたが、私にはかなり「ハッキー」に思えます。私の会社では、Group を参照するグループ変数を宣言しました。

class Company(models.Model):
    ...
    groups = models.ManyToManyField(Group, through='CompanyRole')

CompanyRole は基本的に、グループ名と会社およびグループへの参照を格納します。

class CompanyRole(models.Model):
    group = models.ForeignKey(Group)
    company = models.ForeignKey(Company)
    real_name = models.CharField(max_length=60, verbose_name=_('Real name'))

    objects = CompanyGroupManager()

新しい「企業グループ」を追加する便利な方法でカスタムマネージャーを作成しました

class CompanyGroupManager(models.Manager):
    def create_group(self, company, group_name):
        un_group_name = str(company.id) + '#' + group_name
        group = Group.objects.create(name=un_group_name)
        company_group = self.model(
            real_name=group_name, 
            company=company, 
            group=group
        )

        company_group.save(using=self._db)
        return company_group

ここが、私が特に違和感を感じない部分です。Group モデルの一意の名前に関する問題を変更するために、会社 ID、ハッシュ記号、および実際のグループ名を組み合わせて衝突を回避しました。

私の質問は次のとおりです。私のシナリオにはより良い方法がありますか、何か不足していますか、それとも必要なことを達成するための良い方法ですか?

4

1 に答える 1

2

残念ながら、一意の要件を回避する方法はありません。これは、 https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models のフィールドが ID として使用されているためです。 Field.unique

オプションは次のとおりです。

1) モデルのモック。

基本的には、固有の要件を持たない新しいグループ モデルを作成するだけです。ここでの欠点は、どこでも使用する必要があることです。そのため、サードパーティのアプリを更新する必要がある場合は、価値がない可能性があります.

2) 独自の名前を付けます。(あなたがしたように)

将来のすべてのコーダーが何を見ているかを理解できるように、規則を適切に文書化してください。「会社名」#「グループ名」のようなものは、ID よりも直感的に理解できる可能性があります。ハッシュがどちらかに現れる可能性がある場合は、より特定の区切り文字を使用します (「__」は、django で関連する概念を接続する比較的一般的な方法です。私はこれを使用する可能性があります)。

名前に簡単にアクセスできるように、次を追加することをお勧めします。

def get_name(self):
    # Explain how you get the group name from your uniqueified name
    return self.name.split('#')[1] 

Group.add_to_class('get_name', get_name)

アプリでグループの名前にアクセスするときは、次のようにします。

my_group.get_name()

一意化された名前の生成を save() のオーバーライドされたバージョンに入れることもできます。これにより、モデルとビューをより適切に分割できます...

于 2014-05-15T09:16:31.220 に答える