Фильтр кверисета по связанным объектам в django
Я использовал библиотеку 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.
Я хочу общее правило для фильтрации любых объектов модели в соответствии с его разрешением и разрешением связанных с ним объектов.
Я бы создал специальное поле 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):
return tuple(field for field in model._meta.get_fields() if isinstance(field, PermissionForeignKey))
# in your model
class B(models.Model):
# the model fields
a = PermissionForeignKey(A,on_delete=Model.CASCADE)
# to get the perm fk fields for model B:
perm_fk_fields(B)
# to get field names
tuple(f.name for f in perm_fk_fields(B))