Django'da bir kullanıcının belirli bir grupta olup olmadığını nasıl kontrol edebilirim?


147

Django'nun yönetici sitesinde özel bir grup oluşturdum.

Kodumda, bir kullanıcının bu grupta olup olmadığını kontrol etmek istiyorum. Bunu nasıl yaparım?

Yanıtlar:


118

Gruplara yalnızca groupsözellik üzerinden erişebilirsiniz 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

sonra user.groups.all()geri döner [<Group: Editor>].

Alternatif olarak ve daha doğrudan, bir kullanıcının bir grupta olup olmadığını kontrol ederek şunları yapabilirsiniz:

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

    ...

Not groupnameolabilir ayrıca gerçek Django Grup nesne.


112
Gerçek kontrol şu olurduif user.groups.filter(name=group_name).count(): # do something
Maccesch

144
veya .count () yerine .exists () kullanın
Lie Ryan

3
Soru, ait olduğu grupların Kullanıcı modelini sorgulamakla ilgilidir, nasıl örnekleneceğine değil ... -.-
Jcc.Sanabria

210

Kişisel Kullanıcı nesnesi bağlantılıdır Grup bir içinden nesne ManyToMany ilişkisi.

Böylece filtre yöntemini user.groups öğesine uygulayabilirsiniz .

Bu nedenle, belirli bir Kullanıcının belirli bir grupta (örnek için "Üye") olup olmadığını kontrol etmek için şunu yapın:

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

Belirli bir kullanıcının birden fazla gruba ait olup olmadığını kontrol etmek istiyorsanız __in operatörünü şu şekilde kullanın:

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

Bu işlevlerin, görünümlerinize erişimi yönetmek için @ user_passes_test dekoratörü ile kullanılabileceğini unutmayın:

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

Umarım bu yardım


4
Django'nun DB erişiminin iç işleyişinden emin değilim, ancak bu, bir gruptaki tüm kullanıcıları almak ve standart bir python yapmak user in groups(veya tersi) gibi diğer önerilerden çok daha verimli görünüyor .
brianmearns

1
.exists()Bir boole döndürmek için sonuna eklemeniz gerekmez mi? Aksi takdirde is_member()ve istenen sonucu vermeyebilecek is_in_multiple_groups()bir a döndürür QuerySet.
Michael Bates

4
Django'nun belgelerine göre, queryset'i değerlendirmediğinden, var olmak gerçekten daha hızlıdır (): docs.djangoproject.com/en/dev/ref/models/querysets/#exists
Charlesthk

5
Muhtemelen süper kullanıcının testi geçmesini istiyorsunuz (veritabanını sorgulamadan):def is_member(user): return user.is_superuser or user.groups.filter(...
Dave

is_in_multiple_groupsis_in_some_groupskullanıcının tüm gruplara üye olmasını gerektirmediği için daha açık bir şekilde adlandırılabilir
PeterVermont

15

Bir gruptaki kullanıcıların listesine ihtiyacınız varsa, bunun yerine bunu yapabilirsiniz:

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

ve sonra kontrol et

 if user in users_in_group:
     # do something

kullanıcının grupta olup olmadığını kontrol etmek için.


5
Bu, az sayıda kullanıcısı olan siteler için iyi ölçeklenmez, çünkü her çalıştırıldığında büyük altkümeler kullanıcı tablosunu belleğe yükler.
bhuber

1
user.groups.filter(name="group name").exists()iyi çalışmalı. Yazdığınız çözüm iki sorgu kullanır ve bu nedenle çok uygun değildir.
Noopur Phalak

dediği gibi, "bir gruptaki kullanıcıların listesine ihtiyacınız varsa" ...
Mark Chackerian

15

Sitede kullanıcı örneğine ihtiyacınız yoksa (yaptığım gibi), bunu

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

Bu, veritabanına yalnızca bir istek oluşturur ve bir boole döndürür.


11

Bir kullanıcı belirli bir gruba aitse veya değilse, django şablonlarında aşağıdakiler kullanılarak kontrol edilebilir:

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


1
bu benim için çalışmıyor, grup adı ile karşılaştırma grubu gerektirir gibi görünüyor
hosein

10

Sadece bir satıra ihtiyacınız var:

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
Çok temiz kod olsa ve çok yeniden kullanılamaz, ancak +1 bir satıra almak için.
WhyNotHugo

1

Kullanıcının grubunun önceden tanımlanmış bir grup listesine ait olup olmadığını kontrol etmek istiyorsanız:

def is_allowed(user):
    allowed_group = set(['admin', 'lead', 'manager'])
    usr = User.objects.get(username=user)
    groups = [ x.name for x in usr.groups.all()]
    if allowed_group.intersection(set(groups)):
       return True
    return False


1

Benzer bir durum var, kullanıcının belirli bir grupta olup olmadığını test etmek istedim. Bu yüzden, tüm uygulama boyunca bana yardımcı olan tüm küçük yardımcı programlarımı koyduğum yeni bir utils.py dosyası oluşturdum. Orada, bu tanım var:

utils.py

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

temelde kullanıcı grup company_admin olup olmadığını test ediyorum ve netlik için bu işlevi is_company_admin olarak adlandırdım .

Kullanıcının company_admin içinde olup olmadığını kontrol etmek istediğimde ben sadece bunu yapmak:

views.py

from .utils import *

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

Şimdi, şablonunuzda da aynı şeyi test etmek istiyorsanız, bağlamınıza is_user_admin ekleyebilirsiniz, şuna benzer:

views.py

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

Artık bir şablonda yanıtınızı değerlendirebilirsiniz:

users.html

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

Bu konu başlığında daha önce bulunabilen ancak farklı bir şekilde yapılan cevaplara dayanan basit ve temiz bir çözüm. Umarım birine yardım eder.

Django 3.0.4'te test edilmiştir.


Gözlerinde farklı data = Company.objects.all().filter(id=request.user.company.id)Şirket ne anlama geliyor? Bu senin Modelin mi?
Hayden

Evet @ hayden, bu durumda Şirket benim modelim.
Branko Radojevic

0

Bir satırda:

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

Bu ya Trueya olarak değerlendirilir False.


3
Bu, verimsizdir, çünkü çok daha fazla veri alır ve daha sonra django tarafında çalışır. .exists()Db'nin işi yapmasına izin vermek daha iyi olur .
WhyNotHugo

0

Bunu şu şekilde yaptım. Verimsiz görünüyor ama aklımda başka bir yol yoktu:

@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()

Bu sorgu size kullanıcıyı bildirir: "tom" "admin" grubuna ait olsun veya olmasın


çift ​​altçizeli grup_adı
Trung Lê

0

Ben böyle yaptım. Adlı grup için 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)

şablon

# index.html
{% if is_editor %}
  <h1>Editor tools</h1>
{% endif %}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.