0

英語で、ユーザーのタイプが閲覧者、モデレーター、管理者のいずれであるかを確認したい。

これが私の関連部分ですmodels.py

class UserType( models.Model ) :
    name = models.CharField( max_length = 135 )

    # id |       name
    #----+------------------
    #  1 | tenant
    #  2 | property manager
    #  3 | property owner
    #  4 | vendor manager
    #  5 | vendor
    #  6 | viewer
    #  7 | moderator
    #  8 | administrator

class UserProfile( models.Model ) :
    user       = models.OneToOneField( User )
    user_types = models.ManyToManyField( UserType, null = True, blank = True )

ちなみに、user.profileと同じものに設定しましたuser.get_profile()

私のviews.pyコードでは、チェックを行いたいです。私はそれを理解しました

[ user_type.pk for user_type in user.profile.user_types.all() ]

のようにpkの のリストが表示されます。この特定のユーザーが、テナント (1)、プロパティ マネージャー (2)、およびビューアー (6) であることを意味します。useruser_type[ 1, 2, 6 ]

1つだけチェックしたい場合はuser_type、簡単に実行できます

if 6 in [ user_type.pk for user_type in user.profile.user_types.all() ] :
    # This user is a viewer

しかし、複数の user_types/pks を確認するにはどうすればよいですか? 私は何かをしたかった

# This won't work
if [ 6, 7, 8 ] in [ user_type.pk for user_type in user.profile.user_types.all() ] :
    # This user is either a viewer, moderator, or administrator

user_typesまた、Django-wayをチェックするためのリスト理解の方法はありますか? そうではないようですが、Djangoできれいにクエリする方法がわかりませんでした。

ヒントや提案は大歓迎です。前もって感謝します!

編集:

私は、より多くのDjangoの方法でpksをリストできることを理解しましたvalues_list

user_types = user.profile.user_types.values_list( 'pk', flat = True )
# [ 1, 2, 6 ]

また、このように複数の値を確認できることもわかりました

if len( set( [ 1, 9 ] ).intersection( set( user_types ) ) )
    # True because of 1 is in user_types (don't care about 9)

if len( set( [ 4, 99 ] ).intersection( set( user_types ) ) )
    # False because 4 nor 99 is in user_types

しかし、このset方法でさえ、あまり Django に適しているようには見えません。もっと簡単な方法があるはずですよね?

4

1 に答える 1

2

単に行う:

def has_roles(user, roles):
    return user.profile.user_types.filter(pk__in=roles).count() == len(roles)

print has_roles(user, [6,7,8])

追伸: ハードコードされた PK ID 番号を識別子として使用することは避けたいと思います。あまりにも多くのことがうまくいかない可能性があります。代わりに、実行時にマッピングを定義し、それらを名前で参照します。複数のことが改善されます。

  • あなたのコードははるかに読みやすくなります
  • Django は、DB の最初の項目に一致するモデル インスタンスをオフロードします
  • それ以降は、ID をキャッシュすることができ、DB に再度問い合わせることはありません。

次に、次のことができます。

class UserType( models.Model ):
    TYPES = (( 'tenant', 'Tenant'),
             ( 'propman', 'Property Manager'),
             ( 'propown', 'Property Owner'),
             ( 'vendman', 'Vendor Manager'),
             ( 'vendor', 'Vendor'),
             ( 'viewer', 'Viewer'),
             ( 'moderator', 'Moderator'),
             ( 'admin', 'Administrator'))

    name = models.CharField( max_length = 135, choices=TYPES )

def has_role(user, role):
    return user.profile.user_types.filter(name=role).count() == 1

def has_roles(user, roles):
    return user.profile.user_types.filter(name__in=roles).count() == len(roles)

print has_roles(user, ['viewer','moderator','admin'])

最後に、上記の 2 つの関数を次のように追加できます。

class UserProfile( models.Model ) :
    user       = models.OneToOneField( User )
    user_types = models.ManyToManyField( UserType, null = True, blank = True )


    def has_role(self, role):
        return self.user_types.filter(name=role).count() == 1

    def has_roles(self, roles):
        return self.user_types.filter(name__in=roles).count() == len(roles)

そして、将来的には次のように使用します。

u = User.objects.get(username='me')
if u.userprofile.has_role('admin'):
    print 'I have the powah!'
于 2012-04-09T00:24:57.457 に答える