更新时如何将用户添加到组并创建用户

发布于 2025-01-25 08:39:59 字数 1570 浏览 0 评论 0 原文

我创建了一群堕落的链接的小组: 我订阅了用户类添加了一个名为“角色”的选择字段。基本上,这意味着用户的角色。这样,如果用户扮演“员工”的角色。因此,它将拥有团队工作人员的许可。问题是:我无法让Django按照我的预期做出回应。保存后,我发出了一个信号,该信号应根据他们的角色将用户添加到组中。该程序看起来像这样:

# project/app/model.py

class User(AbstractUser):
    class Roles(models.IntegerChoices):
        SUPER = 0, _('SuperAdmins')
        COMPANY = 1, _('Company')
        UNITY = 2, _('Unity')
        STAFF = 3, _('Staff')

   role: Roles = models.IntegerField(choices=Roles.choices, default=Roles.STAFF, verbose_name=_("Role"))

我的信号就像:

GROUPS = ['SuperAdmins', 'Company', 'Unity', 'Staff']
@receiver(post_save, sender=User)
def user(sender: User, instance: User, created: bool, **kwargs) -> None:
    """
    This receiver function will set every staff pages that is created to the group staff.

    :param sender: the model that will trigger this receiver
    :param instance: the instance
    :param created: if it was already created
    :param kwargs:
    :return: None
    """
    if created:
        group = Group.objects.get(name=GROUPS[instance.role])
        instance.groups.add(group)
    else:
        group = Group.objects.get(name=GROUPS[instance.role])
        instance.groups.add(group)
        print("update")

当我转到管理页面并创建一个新用户时,一切都按预期工作。但是,当我编辑现有用户的角色时,它只是在打印功能上打印“更新”,但没有任何变化。我在做什么错?

I created a bunch of groups fallowing this link: https://stackoverflow.com/questions/22250352/programmatically-create-a-django-group-with-permissions#:~:text
I subscribed the User class adding a choice field called "role". Basically, that means what role that user has. That way if a user has the role of "staff" . Thus It'll have permissions of the group staff. The problem is: I can't get django to respond the way I expected. I put a signal after saving that it should add the user to the group according to their role. The program looks like this:

# project/app/model.py

class User(AbstractUser):
    class Roles(models.IntegerChoices):
        SUPER = 0, _('SuperAdmins')
        COMPANY = 1, _('Company')
        UNITY = 2, _('Unity')
        STAFF = 3, _('Staff')

   role: Roles = models.IntegerField(choices=Roles.choices, default=Roles.STAFF, verbose_name=_("Role"))

My signal is like:

GROUPS = ['SuperAdmins', 'Company', 'Unity', 'Staff']
@receiver(post_save, sender=User)
def user(sender: User, instance: User, created: bool, **kwargs) -> None:
    """
    This receiver function will set every staff pages that is created to the group staff.

    :param sender: the model that will trigger this receiver
    :param instance: the instance
    :param created: if it was already created
    :param kwargs:
    :return: None
    """
    if created:
        group = Group.objects.get(name=GROUPS[instance.role])
        instance.groups.add(group)
    else:
        group = Group.objects.get(name=GROUPS[instance.role])
        instance.groups.add(group)
        print("update")

When I go to the admin page and I create a new user, everything works as expected. But when I edit the role of an existing user, it just prints the "update" fron the print function but nothing changes. What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一身骄傲 2025-02-01 08:39:59

如果有人遇到同样的问题,我将在此处发布解决方案。以及@mtzd的贡献。我根据本文中的问题的描述找到了解决方案的提示: https://stackoverflow.com/a/ 1925784/18600263 。因此,pos_save信号将是:

from django.db import transaction

GROUPS = ['SuperAdmins', 'Company', 'Unity', 'Staff']


@receiver(post_save, sender=User)
def user(sender: User, instance: User, **kwargs) -> None:
    group = Group.objects.get(name=GROUPS[instance.role])
    transaction.on_commit(lambda: instance.groups.set([group], clear=True))

I'll post the solution here in case anyone encounters the same problem. Along with the contribution of @mtzd. I found a tip for the solution based on the description of a problem that was in this post: https://stackoverflow.com/a/1925784/18600263. So the pos_save signal will be:

from django.db import transaction

GROUPS = ['SuperAdmins', 'Company', 'Unity', 'Staff']


@receiver(post_save, sender=User)
def user(sender: User, instance: User, **kwargs) -> None:
    group = Group.objects.get(name=GROUPS[instance.role])
    transaction.on_commit(lambda: instance.groups.set([group], clear=True))
揽月 2025-02-01 08:39:59

使用当前的代码,更改用户角色时,它将被添加到新组中(而不会从上一组中删除)。例如,如果用户最初是组的一部分员工,则其角色更改为 Company ,它将被添加到 Company 组中。由于 user 模型与模型之间的关系是很多与许多关系的关系,因此不会从 staff 组中删除用户。为此,有一些方法(基本上是相同的):

clear 然后 add :

if created:
        group = Group.objects.get(name=GROUPS[instance.role])
        instance.groups.add(group)
    else:
        group = Group.objects.get(name=GROUPS[instance.role])
        instance.groups.clear() # Dissasociates any group the user belonged to
        instance.groups.add(group) # Adds the group

第二个选项:: set set </

if created:
        group = Group.objects.get(name=GROUPS[instance.role])
        instance.groups.add(group)
    else:
        group = Group.objects.get(name=GROUPS[instance.role])
        instance.groups.set([group], clear=True) # Dissasociates any group the user belonged to and sets the new group. clear=True is necessary here because otherwise the Group instances would be deleted

code :这,如果您决定使用第二个选项,则可以使用 set 也适用于正在创建的用户:

GROUPS = ['SuperAdmins', 'Company', 'Unity', 'Staff']
@receiver(post_save, sender=User)
def user(sender: User, instance: User, **kwargs) -> None:
    """
    This receiver function will set every staff pages that is created to the group staff.

    :param sender: the model that will trigger this receiver
    :param instance: the instance
    :param kwargs:
    :return: None
    """
    group = Group.objects.get(name=GROUPS[instance.role])
    instance.groups.set([group], clear=True)

因此,您不必使用创建的参数。有关 clear set 的更多信息,您可以读取docs https://docs.djangoproject.com/en/4.0/ref/ref/ref/models/models/relations/relations/#django.db.models。 fields.recated.releatedmanager.clear 看看如何使用它们!

With your current code, when changing the user role it will be added to a new group (without being removed from the previous one). For example if the user is part of the group Staff initially and then its role changes to Company it will be added to the Company group. As the relationship between the User model and the Group model is a Many to Many relationship, the user won't be removed from the Staff group. To do that there are to ways (which are basically the same):

First option with clear then add:

if created:
        group = Group.objects.get(name=GROUPS[instance.role])
        instance.groups.add(group)
    else:
        group = Group.objects.get(name=GROUPS[instance.role])
        instance.groups.clear() # Dissasociates any group the user belonged to
        instance.groups.add(group) # Adds the group

Second option with set:

if created:
        group = Group.objects.get(name=GROUPS[instance.role])
        instance.groups.add(group)
    else:
        group = Group.objects.get(name=GROUPS[instance.role])
        instance.groups.set([group], clear=True) # Dissasociates any group the user belonged to and sets the new group. clear=True is necessary here because otherwise the Group instances would be deleted

With all this, if you decide to go with the second option, you can go with set also for users that are being created:

GROUPS = ['SuperAdmins', 'Company', 'Unity', 'Staff']
@receiver(post_save, sender=User)
def user(sender: User, instance: User, **kwargs) -> None:
    """
    This receiver function will set every staff pages that is created to the group staff.

    :param sender: the model that will trigger this receiver
    :param instance: the instance
    :param kwargs:
    :return: None
    """
    group = Group.objects.get(name=GROUPS[instance.role])
    instance.groups.set([group], clear=True)

and thus you don't have to use the created param. For more info on clear and set you can read the docs https://docs.djangoproject.com/en/4.0/ref/models/relations/#django.db.models.fields.related.RelatedManager.clear and see how they can be used!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文