Фильтр таблиц содержит все значения в другой таблице

У меня есть 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)
Вернуться на верх