【问题标题】:Filter queryset accouring to related objects in django根据django中的相关对象过滤queryset
【发布时间】:2021-11-24 02:37:18
【问题描述】:

我使用django-guardian库,我想创建Manager来根据用户权限过滤对象。

例如:

 from guardian.shortcuts import get_objects_for_user
 class WithUser(models.Manager):
     user_obj = None
     def assign_user(self,user_obj):
         self.user_obj = user_obj
         qs = super().get_queryset()
         #########################
         # how I know if the current qs have related field and how to get related field managers.
         #???????????????
     def get_queryset(self):
         qs = super().get_queryset()
         if self.user_obj:
              qs = get_objects_for_user(self.user_obj,"view_%s"%self.model.__name__.lower(),qs,accept_global_perms=False)
         return qs

class A(models.Model):
    # the model fields
    objects = WithUser()

class B(models.Model):
    # the model fields
    a = models.ForeignKey(A,on_delete=Model.CASCADE)
    objects = WithUser()

class C(models.Model):
    # the model fields
    b = models.ForeignKey(B,on_delete=Model.CASCADE)
    objects = WithUser()

如何根据C对象的权限和A、B的权限过滤C对象。

我希望通用规则根据其权限和相关对象的权限过滤任何模型对象。

【问题讨论】:

    标签: django django-queryset django-managers django-guardian


    【解决方案1】:

    我会创建一个特殊的 ForeinKey 字段来标记这些字段。

    class PermissionForeignKey(models.ForeignKey):
        # we only use this class to mark the field
        pass
    
    # you can add lru_cache here to speed up
    # you could also move this to the model as @classproperty
    def perm_fk_fields(model):
        fk_fields = []
        for field in model._meta.get_fields():
            if isinstance(field, PermissionForeignKey):
                fk_fields.append(field)
                fk_model_fields = perm_fk_fields(field.remote_field.model)
                if fk_model_fields:
                    fk_fields.append([field, fk_model_fields])
    
        return fk_fields
    
    # in your model
    class B(models.Model):
        # the model fields
        a = PermissionForeignKey(A,on_delete=Model.CASCADE)
    
    

    【讨论】:

    • 好的,谢谢,我会从中受益的。但我想修改相关管理器以将 user_obj 传递给它。
    • 您仍然需要使用“assign_user”方法将 user_object 传递给它。这是与你的经理一起使用的。
    • 看看 C 模型,从中我可以如何将用户传递给 A 的经理。
    • 在这种情况下,您需要使函数递归,我已经更新了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    • 1970-01-01
    • 2019-03-28
    • 2015-12-08
    • 2010-09-20
    • 2019-02-14
    相关资源
    最近更新 更多