【问题标题】:Django grant permissions on/ after saving objectDjango在保存对象后授予权限
【发布时间】:2014-05-21 00:03:46
【问题描述】:

我有一个包含特定权限的 Django 模型。我希望能够为assigned_to field 中的那些用户分配权限。我正在使用django-guardian 来管理权限。

from django.db import models
from django.contrib.auth.models import User
from guardian.shortcuts import assign_perm


class Project(models.Model):
    ...
    assigned_to = models.ManyToManyField(
        User, default=None, blank=True, null=True
    )
    created_by = models.ForeignKey(
        User,
        related_name="%(app_label)s_%(class)s_related"
    )


    permissions = (
        ('view_project', 'View project'),
    )

我尝试实现自定义保存方法。如果我在保存之前尝试这样做:

    def save(self, *args, **kwargs):
        for user in self.assigned_to:
             assign_perm('view_project', user, self)
             super(Project, self).save(*args, **kwargs)

我收到一个错误:

    ObjectNotPersisted: Object <project_name> needs to be persisted first

如果我在保存后这样做(无论如何我猜这是错误的):

    def save(self, *args, **kwargs):
        super(Project, self).save(*args, **kwargs)
        for user in self.assigned_to:
             assign_perm('view_project', user, self)

我收到了Type Error 'ManyRelatedManager' object is not iterable

我应该为此使用post-save 信号吗?对于我认为常见的模式,最好的方法是什么?

【问题讨论】:

    标签: django django-guardian


    【解决方案1】:

    该错误是由于字段本身不可迭代导致的,需要使用filterall指定查询集:

    for user in self.assigned_to.all():
        assign_perm('view_project', user, self)
    

    但是,正如您所评论的,这需要在保存父模型实例后完成,所以是的,您可以创建一个 post_save 信号来完成此操作,或者在调用 @987654325 后将 M2M 关系保存在您的视图中@父实例。

    【讨论】:

    • 其实这行不通。调用了 super 方法,但 self.assigned_to.all() 为空。仅当我稍后显式添加用户时才有效:assigned_to.add([users])。这不是因为Django在保存后实际上添加了ManyToMany相关字段吗?
    • 是的,你是对的。我正在回应您不可迭代的错误并忽略了这一点。我会更新答案。
    猜你喜欢
    • 1970-01-01
    • 2017-07-06
    • 2018-11-20
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多