Djangoでは、ユーザーが特定のグループに属しているかどうかを確認するにはどうすればよいですか?


146

Djangoの管理サイトでカスタムグループを作成しました。

私のコードでは、ユーザーがこのグループに属しているかどうかを確認したいと思います。それ、どうやったら出来るの?

回答:


117

groups上の属性を使用するだけでグループにアクセスできますUser

from django.contrib.auth.models import User, Group

group = Group(name = "Editor")
group.save()                    # save this new group for this example
user = User.objects.get(pk = 1) # assuming, there is one initial user 
user.groups.add(group)          # user is now in the "Editor" group

次にをuser.groups.all()返します[<Group: Editor>]

または、さらに直接、ユーザーがグループに含まれているかどうかを次の方法で確認できます。

if django_user.groups.filter(name = groupname).exists():

    ...

注意groupnameすることができますまた、実際のDjangoのグループオブジェクトです。


112
実際のチェックは次のようになりますif user.groups.filter(name=group_name).count(): # do something
Maccesch

144
または.count()の代わりに.exists()を使用します
Lie Ryan

3
問題は、それをインスタンス化する方法ではなく、所属するグループのユーザーモデルをクエリすることです... -.-
Jcc.Sanabria

210

あなたのユーザーオブジェクトがにリンクされているグループを通じてオブジェクト多対多関係。

これにより、フィルターメソッドをuser.groupsに適用できます。

したがって、特定のユーザーが特定のグループ(例では「メンバー」)に属しているかどうかを確認するには、次のようにします。

def is_member(user):
    return user.groups.filter(name='Member').exists()

特定のユーザーが複数の特定のグループに属しているかどうかを確認するには、次のように__in演算子を使用します。

def is_in_multiple_groups(user):
    return user.groups.filter(name__in=['group1', 'group2']).exists()

これらの関数を@user_passes_testデコレーターで使用して、ビューへのアクセスを管理できることに注意してください。

from django.contrib.auth.decorators import login_required, user_passes_test
@login_required
@user_passes_test(is_member) # or @user_passes_test(is_in_multiple_groups)
def myview(request):
    # Do your processing

この助けを願っています


4
私はdjangoのDBアクセスの内部の仕組みについてはわかりませんが、これは他のいくつかの提案よりもはるかに効率的であるように思われuser in groupsます。
brianmearns 2013

1
.exists()ブール値を返すために最後に追加する必要はありませんか?そうでない場合is_member()is_in_multiple_groups()返されますQuerySet望ましい結果が得られない可能性があります。
マイケルベイツ

4
Djangoのドキュメントによると、それは確かに高速です、それはクエリセット評価しませんので、使用が)(存在する:docs.djangoproject.com/en/dev/ref/models/querysets/#exists
Charlesthk

5
おそらく、スーパーユーザが(データベースを照会せずに)テストに合格したい:def is_member(user): return user.is_superuser or user.groups.filter(...
デイブ

is_in_multiple_groupsis_in_some_groupsユーザーがすべてのグループのメンバーである必要がないため、より明示的に名前を
付ける

15

グループ内のユーザーのリストが必要な場合は、代わりに次のようにできます。

from django.contrib.auth.models import Group
users_in_group = Group.objects.get(name="group name").user_set.all()

そしてチェック

 if user in users_in_group:
     # do something

ユーザーがグループに属しているかどうかを確認します。


5
実行するたびに大きなサブセットのユーザーテーブルをメモリにロードするため、ユーザー数が少ないサイトの場合、これはうまくスケーリングしません。
bhuber 2013年

1
user.groups.filter(name="group name").exists()正常に動作するはずです。作成したソリューションは2つのクエリを使用するため、あまり最適ではありません。
Noopur Phalak

それが言うように、「グループにいるユーザーのリストが必要な場合」...
Mark Chackerian

15

(私がしたように)ユーザーインスタンスがサイトに必要ない場合は、

User.objects.filter(pk=userId, groups__name='Editor').exists()

これにより、データベースに対する要求が1つだけ生成され、ブール値が返されます。


11

ユーザーが特定のグループに属しているかどうかは、次を使用してdjangoテンプレートで確認できます。

{% if group in request.user.groups.all %} "some action" {% endif %}


1
これは私にとっては
うまくいき

10

必要なのは1行だけです。

from django.contrib.auth.decorators import user_passes_test  

@user_passes_test(lambda u: u.groups.filter(name='companyGroup').exists())
def you_view():
    return HttpResponse("Since you're logged in, you can see this text!")

4
ただし、あまりクリーンなコードではなく、再利用もできませんが、1行にまとめるための+1。
WhyNotHugo 2015


1

私も同じような状況で、ユーザーが特定のグループに属しているかどうかをテストしたいと思いました。それで、新しいファイルutils.pyを作成しました。ここには、アプリケーション全体を支援する小さなユーティリティをすべて入れました。そこで、私はこの定義を持っています:

utils.py

def is_company_admin(user):
    return user.groups.filter(name='company_admin').exists()

基本的に、ユーザーがグループcompany_adminに属しているかどうかをテストしています。わかりやすくするために、この関数をis_company_adminと呼びました。。。

ユーザーがcompany_adminにいるかどうかを確認するときは、次のようにします。

views.py

from .utils import *

if is_company_admin(request.user):
        data = Company.objects.all().filter(id=request.user.company.id)

テンプレートで同じようにテストしたい場合は、次のように、コンテキストにis_user_adminを追加できます。

views.py

return render(request, 'admin/users.html', {'data': data, 'is_company_admin': is_company_admin(request.user)})

これで、テンプレートで応答を評価できます。

users.html

{% if is_company_admin %}
     ... do something ...
{% endif %}

このスレッドの最初の方で見つかる可能性があるが、異なる方法で行われた回答に基づく、シンプルでクリーンなソリューション。それが誰かを助けることを願っています。

Django 3.0.4でテスト済み。


あなたのdata = Company.objects.all().filter(id=request.user.company.id)では、会社は何を意味しますか?それはあなたのモデルですか?
ヘイデン

はい、@ hayden、この場合、会社が私のモデルです。
Branko Radojevic

0

1行で:

'Groupname' in user.groups.values_list('name', flat=True)

これは、Trueまたはに評価されますFalse


3
これは、より多くのデータをフェッチし、django側で操作するため、非効率的です。.exists()データベースに仕事をさせるために使う方が良いです。
WhyNotHugo 2015

0

私はそれを次の方法で行いました。効率が悪いようですが、私は他に方法がありませんでした。

@login_required
def list_track(request):

usergroup = request.user.groups.values_list('name', flat=True).first()
if usergroup in 'appAdmin':
    tracks = QuestionTrack.objects.order_by('pk')
    return render(request, 'cmit/appadmin/list_track.html', {'tracks': tracks})

else:
    return HttpResponseRedirect('/cmit/loggedin')

0

User.objects.filter(username='tom', groups__name='admin').exists()

そのクエリはユーザーに通知します:「tom」グループ「admin」に属しているかどうか


2つの下線付きgroups__name
チュンLê

0

こうやってやった。というグループの場合Editor

# views.py
def index(request):
    current_user_groups = request.user.groups.values_list("name", flat=True)
    context = {
        "is_editor": "Editor" in current_user_groups,
    }
    return render(request, "index.html", context)

テンプレート

# index.html
{% if is_editor %}
  <h1>Editor tools</h1>
{% endif %}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.