在Django 1.9中将​​用户添加到保存组中

时间:2017-01-10 16:48:55

标签: python django

您好,我正在使用Django 1.9。尝试在创建或保存时将用户添加到组。 使用user.groups或groups.user_set.add不能正常工作,混合搭配下面的保存前后。

这些答案对我不起作用,所以这不是一个骗局: Adding user to group on creation in Django
Adding a user to a group in django
Add users to groups in Django

我在保存前处理程序和后保存处理程序中都尝试了这两种方法。

@receiver(pre_save, sender=User)
def user_presave_handler(sender, instance, **kwargs):
    if instance.is_staff and not instance.is_superuser:
        # Grant all permissions
        try:
            instance.groups.add(Group.objects.get(name='staff_user'))
        except Group.DoesNotExist:
            pass

@receiver(post_save, sender=User)
def user_postsave_handler(sender, instance, **kwargs):
    if instance.is_staff and not instance.is_superuser:
        try:
            g = Group.objects.get(name='staff_user')
        except Group.DoesNotExist:
            pass
        else:
            g.user_set.add(instance)
            g.save()

你可以混合搭配使用哪种方法,我试过了。我不会在测试中使用多种方法。点击用户管理页面上的保存按钮后,用户不会显示在组中。

我仔细检查了处理程序是否被调用,用户逻辑是否正确等等。

我做错了什么,或者在1.9中有什么改变来打破旧方法?

谢谢!

编辑: 对于那些要求,该组创建如下:

group, __ = Group.objects.get_or_create(name='staff_user')

permissions = Permission.objects.all()
for p in permissions:
    group.permissions.add(p)
group.save()

我已经调试了它,该组肯定存在,但也许我做错了所以它不会被应用?

3 个答案:

答案 0 :(得分:3)

我认为这与此相关:Issue with ManyToMany Relationships not updating inmediatly after save。有人在评论中报告说它在1.10仍然是最新的。

问题是您还可以在管理员选择群组'添加用户'页;然后当您保存用户时,会发生以下情况:

  1. 用户已保存
  2. 发生保存后信号,并将用户添加到组
  3. 清除用户的所有组
  4. 在添加用户页面上选择的组将添加到用户。
  5. 显然,您可以使用m2m_changed信号。我从未使用它,但我认为这样的事情应该有效:

    from django.db.signals import m2m_changed
    
    @receiver(m2m_changed, sender=User.groups.through)
    def user_groups_changed_handler(sender, instance, action, **kwargs):
        if action == 'post_add' and instance.is_staff and not instance.is_superuser:
            if not instance.groups.filter(name='staff_user').exists():
                try:
                    g = Group.objects.get(name='staff_user')
                except Group.DoesNotExist:
                   pass
                else:
                    instance.groups.add(g)
    

    这假设信号接收的instance是用户,否则它看起来会略有不同。检查操作并检查是否已添加组是为了防止无限循环。发件人是隐藏的'通过'表格为多对多关系User.groups.through

答案 1 :(得分:1)

就我而言,我试图将is_staff属性映射到名为“ staff”的组。多亏@RemcoGerlich的回答,我终于能够提出对我有用的东西:

@receiver(post_save, sender=User)
def save_user_person(sender, instance, **kwargs):
    user = instance
    instance.person.save()
    group = Group.objects.get(name='staff')
    if user.is_staff and not user.groups.filter(name='staff').exists():
        user.groups.add(group)
    elif not user.is_staff and user.groups.filter(name='staff').exists():
        user.groups.remove(group)

@receiver(m2m_changed, sender=User.groups.through)
def sync_staff_to_group(instance, action, **kwargs):
    user = instance
    if action == 'post_remove' or action == 'post_add' or action == 'post_clear':
        group = Group.objects.get(name='staff')
        if user.is_staff and not user.groups.filter(name='staff').exists():
            user.groups.add(group)
        elif not user.is_staff and user.groups.filter(name='staff').exists():
            user.groups.remove(group)

答案 2 :(得分:0)

Python 3,Django == 2.1.7

def add_user_to_group(sender, instance: User, created: bool, **kwargs):
    try:
        if created:
            group = Group.objects.get(name=instance.user_type)
            instance.groups.add(group)
            instance.save()
    except Group.DoesNotExist:
        pass


models.signals.post_save.connect(add_user_to_group, sender=User)