Нет проблем, вам нужно создать такие разрешения и вручную реализовать контроль доступа с поддержкой django-guardian.
Контроль доступа нравится?
Как я могу реализовать эту функцию?
Django-guardian - это библиотека контроля доступа для любого объекта. Таким объектом также могут быть группы. См. Контроль доступа в примере проекта. См. Https://github.com/django-guardian/django-guardian/blob/devel/example_project/articles/views.py#L35 .
Идеально!
Это мой фрагмент кода:
def create_user_profile(sender, instance, created, **kwargs):
print("create_user_profile")
try:
print("created: "+ str(created))
if created:
Profile.objects.create(user=instance)
print("Member.objects.get_or_create(django_user=instance)")
#Create a user into groups_manager_member
member = Member.objects.create(django_user=instance, first_name=instance.first_name, last_name=instance.last_name, username=instance.username, email=instance.email)
print("member instance created")
print(member)
print("Group.objects.create(name=ID_GROUP+instance.username)")
#Create a group into groups_manager_group
group = Group.objects.create(name=ID_GROUP+instance.username)
print("group instance created")
print(group)
#Add member into the group correct
group.add_member(member=member)
print("member added into the group correct")
except Exception as e:
print("Exception: "+str(e))
pass
def save_user_profile(sender, instance, **kwargs):
print("save_user_profile")
try:
instance.profile.save()
except Exception as e:
print("Exception: "+str(e))
pass
post_save.connect(create_user_profile, sender=User)
post_save.connect(save_user_profile, sender=User)
Мне нужно иметь разрешение на добавление / удаление для всех пользователей группы.
Не знаю, где у вас проблема. Вам понадобится что-то вроде:
class ProtectedGroupUpdateView(PermissionRequiredMixin, GroupUpdateView):
permission_required = ['change_group', ]
...
и назначить разрешение группе при создании.
Я попытался добавить разрешение «может добавить участника», но это возможно для всех групп, а не для персонала.
Я не понимаю, что вы имеете в виду. Привилегии django-guardian всегда предоставляются пользователям или группам пользователей. Невозможно предоставить привилегии на основе ролей или особых условий. Если вы хотите предоставить сотрудникам разрешение на управление группой «X», создайте группу «Персонал», добавьте в нее сотрудников, добавьте группу «X» и дайте группе «Персонал» разрешение на управление «X» группа.
Мне нужен пользователь, который принадлежит к группе
«X» может добавлять или удалять только для группы «X», к сожалению, сейчас это не так, если у вас есть разрешение «вы можете добавлять пользователей», вы можете делать это для всех групп, а не для ученика.
Извините за мой плохой английский
К сожалению, я не могу понять ваших ожиданий. Внимательно изучите пример проекта . В таком случае этого должно быть достаточно.
"X" can add or remove only for group "X"
означает:
Мне действительно нужно убедиться, что пользователь, принадлежащий к группе "x", сможет добавлять или удалять только других пользователей из своей группы.
@ Allan-Nava, привилегии django-guardian всегда предоставляются пользователям или группам пользователей. Невозможно предоставить привилегии на основе ролей или особых условий. Если вы хотите, чтобы пользователи управляли своими группами, дайте группе разрешение управлять этой группой как объектом.
Вы понимаете, как назначить и проверить разрешение группы «X» для управления группой «X»?
Это должно быть похоже на netflix (но у всех участников есть возможность войти в систему): у каждого пользователя должна быть личная группа, в которой он может добавлять или удалять пользователей в зависимости от того, что он предпочитает. Проблема в том, что если вы дадите это разрешение, добавьте пользователей, и это повлияет на все другие группы, а не на пользователей, которые принадлежат к этой.
Проблема в том, что если вы дадите это разрешение, добавьте пользователей, и это повлияет на все другие группы, а не на пользователей, которые принадлежат к этой.
Это определенно неправда. Это предложение верно для ядра Django. Если вы используете правильное разрешение Django-guardian, предоставленное группе управления X для группы X, применяется только к группе X. Как и в примере проекта, предоставление права на управление определенной статьей не означает, что другие статьи можно редактировать. этим пользователем.
Я хочу создать единое разрешение, которое позволяет всем пользователям добавлять других людей в свою группу членства. Каждый раз, когда я создаю нового пользователя с его группой членства «X», я хочу, чтобы было создано новое разрешение под названием «Может добавлять группу для X», и это разрешение должно иметь группу «X» в качестве объекта.
Нравится:
def create_user_profile(sender, instance, created, **kwargs):
print("create_user_profile")
try:
print("created: "+ str(created))
if created:
Profile.objects.create(user=instance)
print("Member.objects.get_or_create(django_user=instance)")
#Create a user into groups_manager_member
member = Member.objects.create(django_user=instance, first_name=instance.first_name, last_name=instance.last_name, username=instance.username, email=instance.email)
print("member instance created")
print(member)
print("Group.objects.create(name=ID_GROUP+instance.username)")
#Create a group into groups_manager_group
group = Group.objects.create(name=ID_GROUP+instance.username)
print("group instance created")
print(group)
#Add member into the group correct
group.add_member(member=member)
print("member added into the group correct")
UserObjectPermission.objects.assign_perm('can_add_member_for_xgroup', member, obj=group)
except Exception as e:
print("Exception: "+str(e))
pass
def save_user_profile(sender, instance, **kwargs):
print("save_user_profile")
try:
instance.profile.save()
except Exception as e:
print("Exception: "+str(e))
pass
post_save.connect(create_user_profile, sender=User)
post_save.connect(save_user_profile, sender=User)
Ненормальным является создание тысячи разрешений. assign_perm('manage_group',group,group)
или assign_perm('manage_group',user,group)
должно хватить. Остальное - проверить, есть ли у пользователя полномочия на управление определенной группой.
Хорошо, отлично, но как я могу проверить в режиме просмотра Templare?
{{perms.groups_manager.canaddmemberx2}}
@ ad-m Хорошо, спасибо, мой фрагмент кода:
from guardian.shortcuts import assign_perm
def create_user_profile(sender, instance, created, **kwargs):
print("create_user_profile")
try:
print("created: "+ str(created))
if created:
Profile.objects.create(user=instance)
print("Member.objects.get_or_create(django_user=instance)")
#Create a user into groups_manager_member
member = Member.objects.create(django_user=instance, first_name=instance.first_name, last_name=instance.last_name, username=instance.username, email=instance.email)
print("member instance created")
print(member)
print("Group.objects.create(name=ID_GROUP+instance.username)")
#Create a group into groups_manager_group
group = Group.objects.create(name=ID_GROUP+instance.username)
print("group instance created")
print(group)
#Add member into the group correct
group.add_member(member=member)
print("member added into the group correct")
#UserObjectPermission.objects.assign_perm('can_add_member_for_xgroup', member, obj=group)
assign_perm('groups_manager.can_add_member_custom', member, group)
except Exception as e:
print("Exception: "+str(e))
pass
def save_user_profile(sender, instance, **kwargs):
print("save_user_profile")
try:
instance.profile.save()
except Exception as e:
print("Exception: "+str(e))
pass
post_save.connect(create_user_profile, sender=User)
post_save.connect(save_user_profile, sender=User)
@ ad-m Я пробовал этот код, но у меня возникла исключительная ситуация.
#Add member into the group correct
group.add_member(member=member)
print("member added into the group correct")
#Assign permission for the groups
assign_perm('groups_manager.can_add_member_custom', member, group)
print("assign_perm('groups_manager.can_add_member_custom', member, group)")
@ Allan-Nava, что вам непонятно в сообщении об ошибке?
@ ad-m
У меня такая ошибка:
def create_user_profile(sender, instance, created, **kwargs):
print("create_user_profile")
try:
print("created: "+ str(created))
if created:
Profile.objects.create(user=instance)
print("Member.objects.get_or_create(django_user=instance)")
#Create a user into groups_manager_member
member = Member.objects.create(django_user=instance, first_name=instance.first_name, last_name=instance.last_name, username=instance.username, email=instance.email)
print("member instance created")
print(member)
print("Group.objects.create(name=ID_GROUP+instance.username)")
#Create a group into groups_manager_group
group = Group.objects.create(name=ID_GROUP+instance.username)
print("group instance created")
print(group)
#Add member into the group correct
group.add_member(member=member)
print("member added into the group correct")
#Assign permission for the groups
assign_perm('groups_manager.can_add_member_custom', instance, group)
print("assign_perm('groups_manager.can_add_member_custom', instance, group)")
except Exception as e:
print("Exception: "+str(e))
pass
@ Allan-Nava, что вам непонятно в сообщении об ошибке?
@ ad-m Я не понимаю, в чем проблема
@ Allan-Nava, такого разрешения нет. Прочтите документы, какие разрешения существуют .
Хорошо, я прочитал, но мне нужно создать разрешение N для N групп / пользователей при создании нового пользователя?
content_type = ContentType.objects.get_for_model(Group)
permission = Permission.objects.create(
codename='can_add_member_custom',
name='Can Add Member Custom',
content_type=content_type,
)
Как было сказано ранее :
Ненормальным является создание тысячи разрешений.
Одно разрешение для каждого типа действия.
Как было сказано ранее:
Ненормальным является создание тысячи разрешений.
Одно разрешение для каждого типа действия.
Хорошо, но как я могу создать общее разрешение?
Как сказано в основных документах Django. Связано выше.
Хорошо, я использую Django Groups Manager:
Это моя модельная группа :
class Group(GroupMixin):
group_type = models.ForeignKey(GroupType, null=True, blank=True, on_delete=models.SET_NULL,
related_name='%(app_label)s_%(class)s_set')
group_entities = models.ManyToManyField(GroupEntity, blank=True,
related_name='%(app_label)s_%(class)s_set')
django_group = models.ForeignKey(DjangoGroup, null=True, blank=True, on_delete=models.SET_NULL)
group_members = models.ManyToManyField(Member, through='GroupMember',
related_name='%(app_label)s_%(class)s_set')
# this is just required for easy explanation
class Meta(GroupMixin.Meta):
abstract = False
permissions = (
('can_add_member_custom', 'Can Add Member Custom'),
)
А это мой профиль модели:
from __future__ import unicode_literals
import hashlib
import os.path
import urllib
from django.conf import settings
from django.contrib.auth.models import User
from django.db import models
from django.db.models.signals import post_save
from django.utils.encoding import python_2_unicode_compatible
from bootcamp.activities.models import Notification
#Custom class - ParentsProfile
from bootcamp.parents.models import ParentsProfile
#Custom class - MemberMixin TO CREATE INTO groups_manager_member
from bootcamp.groups_manager.models import MemberMixin, Member, Group
#Import django guardian assign_perm
from guardian.shortcuts import assign_perm
#import UserObjectPermission
from guardian.models import UserObjectPermission
import datetime
ID_GROUP = "Group_"
'''
User Model - Authentication
'''
<strong i="12">@python_2_unicode_compatible</strong>
class Profile(models.Model):
user = models.OneToOneField(User)
location = models.CharField(max_length=50, null=True, blank=True)
url = models.CharField(max_length=50, null=True, blank=True)
job_title = models.CharField(max_length=50, null=True, blank=True)
#I need to delete the parents application
#Other tascout attributes
birthdate = models.DateField(default=datetime.date.today)
address = models.CharField(max_length=255, null=True, blank=True)
main_role = models.CharField(max_length=255, null=True, blank=True)
other_roles = models.CharField(max_length=255, null=True, blank=True)
mobile = models.CharField(max_length=255, null=True, blank=True)
background_photo = models.CharField(max_length=255, null=True, blank=True)
profile_photo = models.CharField(max_length=255, null=True, blank=True)
biography = models.TextField(null=True, blank=True)
idols = models.TextField(null=True, blank=True)
weight = models.IntegerField(default=0)
height = models.IntegerField(default=0)
favorite_team = models.CharField(max_length=255, null=True, blank=True)
level = models.IntegerField(default=0)
sex = models.CharField(max_length=1, default="M")
nationality = models.CharField(max_length=255, null=True, blank=True)
city = models.CharField(max_length=255, null=True, blank=True)
postal_code = models.CharField(max_length=255, null=True, blank=True)
province = models.CharField(max_length=255, null=True, blank=True)
number = models.CharField(max_length=255, null=True, blank=True)
latitude = models.DecimalField( null=True, blank=True, max_digits=9, decimal_places=6)
longitude = models.DecimalField( null=True, blank=True, max_digits=9, decimal_places=6)
class Meta:
db_table = 'auth_profile'
def __str__(self):
return self.user.username
def get_url(self):
url = self.url
if "http://" not in self.url and "https://" not in self.url and len(self.url) > 0: # noqa: E501
url = "http://" + str(self.url)
return url
def get_picture(self):
no_picture = settings.MEDIA_URL +'/profile_pictures/user.png'
try:
filename = settings.MEDIA_ROOT + '/profile_pictures/' +\
self.user.username + '.jpg'
picture_url = settings.MEDIA_URL + 'profile_pictures/' +\
self.user.username + '.jpg'
if os.path.isfile(filename): # pragma: no cover
return picture_url
else: # pragma: no cover
gravatar_url = 'http://www.gravatar.com/avatar/{0}?{1}'.format(
hashlib.md5(self.user.email.lower()).hexdigest(),
urllib.urlencode({'d': no_picture, 's': '256'})
)
return gravatar_url
except Exception:
return no_picture
#Retrieve users' cover
def get_cover(self):
no_cover = settings.MEDIA_ROOT +'profile_covers/cover.jpg'
try:
filename = settings.MEDIA_ROOT + '/profile_covers/' +\
self.user.username + '.jpg'
cover_url = settings.MEDIA_URL + 'profile_covers/' +\
self.user.username + '.jpg'
if os.path.isfile(filename) and os.path.exists(filename): # pragma: no cover
if cover_url != None:
return cover_url
else:
return no_cover
else:
no_cover
except Exception:
return no_cover
def get_screen_name(self):
try:
if self.user.get_full_name():
return self.user.get_full_name()
else:
return self.user.username
except:
return self.user.username
def notify_liked(self, feed):
if self.user != feed.user:
Notification(notification_type=Notification.LIKED,
from_user=self.user, to_user=feed.user,
feed=feed).save()
def unotify_liked(self, feed):
if self.user != feed.user:
Notification.objects.filter(notification_type=Notification.LIKED,
from_user=self.user, to_user=feed.user,
feed=feed).delete()
def notify_commented(self, feed):
if self.user != feed.user:
Notification(notification_type=Notification.COMMENTED,
from_user=self.user, to_user=feed.user,
feed=feed).save()
def notify_also_commented(self, feed):
comments = feed.get_comments()
users = []
for comment in comments:
if comment.user != self.user and comment.user != feed.user:
users.append(comment.user.pk)
users = list(set(users))
for user in users:
Notification(notification_type=Notification.ALSO_COMMENTED,
from_user=self.user,
to_user=User(id=user), feed=feed).save()
def notify_favorited(self, question):
if self.user != question.user:
Notification(notification_type=Notification.FAVORITED,
from_user=self.user, to_user=question.user,
question=question).save()
def unotify_favorited(self, question):
if self.user != question.user:
Notification.objects.filter(
notification_type=Notification.FAVORITED,
from_user=self.user,
to_user=question.user,
question=question).delete()
def notify_answered(self, question):
if self.user != question.user:
Notification(notification_type=Notification.ANSWERED,
from_user=self.user,
to_user=question.user,
question=question).save()
def notify_accepted(self, answer):
if self.user != answer.user:
Notification(notification_type=Notification.ACCEPTED_ANSWER,
from_user=self.user,
to_user=answer.user,
answer=answer).save()
def unotify_accepted(self, answer):
if self.user != answer.user:
Notification.objects.filter(
notification_type=Notification.ACCEPTED_ANSWER,
from_user=self.user,
to_user=answer.user,
answer=answer).delete()
def create_user_profile(sender, instance, created, **kwargs):
print("create_user_profile")
try:
print("created: "+ str(created))
if created:
Profile.objects.create(user=instance)
print("Member.objects.get_or_create(django_user=instance)")
#Create a user into groups_manager_member
member = Member.objects.create(django_user=instance, first_name=instance.first_name, last_name=instance.last_name, username=instance.username, email=instance.email)
print("member instance created")
print(member)
print("Group.objects.create(name=ID_GROUP+instance.username)")
#Create a group into groups_manager_group
group = Group.objects.create(name=ID_GROUP+instance.username)
print("group instance created")
print(group)
#Add member into the group correct
group.add_member(member=member)
print("member added into the group correct")
#Assign permission for the groups
assign_perm('can_add_member_custom', instance, group)
#print("assign_perm('can_add_member_custom', instance, group)")
except Exception as e:
print("Exception: "+str(e))
pass
def save_user_profile(sender, instance, **kwargs):
print("save_user_profile")
try:
instance.profile.save()
except Exception as e:
print("Exception: "+str(e))
pass
post_save.connect(create_user_profile, sender=User)
post_save.connect(save_user_profile, sender=User)
Django-guardian - это управление разрешениями для одного объекта, поэтому предоставьте разрешение одному пользователю / группе для одного объекта.
Хорошо, отлично, но все еще не работает, хотя я добавил разрешение в группе моделей
Что не работает?
Эта строка:
#Assign permission for the groups
assign_perm('can_add_member_custom', instance, group)
print("assign_perm('can_add_member_custom', instance, group)")
instance - это объект пользователя, но я добавляю в модель Group разрешение
# this is just required for easy explanation
class Meta(GroupMixin.Meta):
abstract = False
permissions = (
('can_add_member_custom', 'Can Add Member Custom'),
)
Я использовал этот django-groups-manager
Я тупой, мне нужно делать миграции и мигрировать:
python3 manage.py makemigrations
python3 manage.py migrate
Спасибо за терпение 👍 @ ad-m
Но как я могу проверить в представлении шаблона?
это:
jack.has_perm('change_group', admins)
С оболочкой django это работает: