Фильтр таблиц содержит все значения в другой таблице
У меня есть 2 таблицы Product и user и в каждой таблице есть список разрешений, мне нужно перечислить пользователю весь продукт так, чтобы у пользователя были все разрешения на продукт
проверьте представление кода:
Модель продукта:
class Product(TimeStampedModel, SoftDeletableModel):
title = models.CharField(max_length=255, unique=True)
permission = models.ManyToManyField(Permission, related_name="Permissions")
и это модель пользователя:
class User(AbstractBaseUser, SoftDeletableModel):
display_name = models.CharField(max_length=64, blank=True)
permission = models.ManyToManyField(Permission, related_name="Permissions")
допустим, у нас есть следующие данные:
разрешения пользователя1 A1,A2,C1,C2,C3
разрешения пользователя2 A1,A2,B1,B2,C1,C2,C3
продукт имеет разрешения A1,B1,C1
пользователь1 не может видеть продукт "не имеет разрешения B1"
пользователь2 может видеть товар
я попробовал следующее:
Products.objects.filter(permission__in=user.permission.values("id"))
также попробовал этот sql запрос:
Select * from products p
Inner join productspermession pp
On p.id = pp.product_id
Inner join userpermessions up on pp.permession_id = up.permession_id
where up.user_id = 1
Вам необходимо изменить использование отношений. Вы установили related_name здесь:
related_name="Permissions"
Но затем вы пробуете следующее:
user.permission.values("id")
Мое предложение состоит в том, чтобы изменить related_name в обеих моделях на этот тип snake_case:
related_name="permissions"
Затем вы можете отфильтровать их (предполагая, что permission является объектом Permission):
Products.objects.filter(permission__in=user.permissions.all())
# I cannot check right now, but I think this also works:
Products.objects.filter(permission=permission)
я решил эту проблему, проверив, к каким продуктам пользователь не может получить доступ и исключил product_ids из запроса фильтрации продуктов
- Определите новую модель для представления отношения "продукт-разрешение" "я не смог напрямую обратиться к модели ManyToMany"
это новое представление модели:
class ProductPermission(models.Model):
product = models.ForeignKey("Product", related_name="product_permission", on_delete=models.CASCADE)
permission = models.ForeignKey(
DisclosureCenter, related_name="product_permission", on_delete=models.CASCADE
)
class Product(TimeStampedModel, SoftDeletableModel):
title = models.CharField(max_length=255, unique=True)
permissions = models.ManyToManyField(Permission, through="ProductPermission")
и в части фильтра я делаю следующее
excluded_products = ProductPermission.objects.filter(~Q(disclosure_center__in=user.permissions.values("id"))).all()
excluded_product_ids = [excluded_product.product_id for excluded_product in excluded_products]
products = Product.filter(is_removed=False).exclude(id__in= excluded_product_ids)