Django запрос на основе сквозной таблицы

У меня есть 5 моделей, которые являются Contents, Filters, ContentFilter , Users.

пользователь может просматривать содержимое. содержимое может быть ограничено с помощью фильтров, чтобы пользователи не могли его видеть.

вот модели.

class Content(models.Model):
    title = models.CharField(max_length=120)
    text = models.TextField()
    filters = models.ManyToManyField(to="Filter", verbose_name=_('filter'), blank=True, related_name="filtered_content",through='ContentFilter')

class Filter(models.Model):
    name = models.CharField(max_length=255, verbose_name=_('name'), unique=True)
    added_user = models.ManyToManyField(to=User, related_name="added_user", blank=True)
    ignored_user = models.ManyToManyField(to=User, related_name="ignored_user", blank=True)
    charge_status = models.BooleanField(blank=True, verbose_name=_('charge status'))

class ContentFilter(models.Model):
    content = models.ForeignKey(Content, on_delete=models.CASCADE)
    filter = models.ForeignKey(Filter, on_delete=models.CASCADE)
    manual_order = models.IntegerField(verbose_name=_('manual order'), default=0,rst'))
    access = models.BooleanField(_('has access'))

Что это означает, что существует 5 содержимых (1,2,3,4,5).

2 пользователя существуют. x,y

Можно создать фильтр с игнорируемым пользователем (x).

Содержание 1,2,3 имеет отношение к фильтру x.

теперь X видит 4,5, а Y видит 1,2,3,4,5


Сейчас я делаю так: на основе того, какой пользователь запросил, нахожу, какие фильтры связаны с ним. затем запрашиваю сквозную таблицу (ContentFilter), чтобы найти, какое содержимое пользователь не может видеть, и затем исключаю его из всего содержимого. (это помогает при больших объединениях)

filters = Filter.objects.filter(Q(added_user=user)|(Q(ignored_user=user))
excluded_contents = list(ContentFilter.objects.filter(filter__in=filters).values_list('id',flat=True))
contents = Contents.objects.exclude(id__in=excluded_contents)

Проблема

Мне нужен способ, чтобы фильтры могли иметь порядок и фильтровать набор запросов на основе топ ContentFilter для каждого пользователя. например, контент 1 может быть заблокирован для всех пользователей с помощью 1 фильтра (фильтр x, где игнорируемый пользователь имеет всех пользователей). но в ContentFilter имеет ручной_порядок 0.

тогда во втором фильтре все пользователи, у которых статус заряда True, могут видеть это содержимое. (фильтр y, где добавленный пользователь имеет всех пользователей и статус заряда True). и в ContentFilter имеет manual_order равный 1.

Я думаю, что могу сделать это с помощью цикла for, чтобы проверить все содержимое и выбрать самые верхние ContentFilter из них на основе фильтров, включающих этого пользователя, но это требует много времени и ресурсов.

и я предпочитаю не использовать необработанный SQL, но я не уверен, есть ли способ сделать это с помощью django orm

Мне удалось решить эту проблему с помощью Subquery.

сначала я создаю список фильтров, в которые входит пользователь.

filters = Filter.objects.filter(Q(added_user=user)|(Q(ignored_user=user))

затем я создаю подзапрос для присвоения каждому содержимому значения доступа (если к нему применен какой-либо фильтр)

current_used_filters = ContentFilter.objects.filter(Q(filter__in=user_filters),content=OuterRef('pk')).order_by('-manual_order')
blocked_content_list = Content.objects.annotate(access=Subquery(current_used_filters.values('access')[:1])).filter(
        access=False).values_list('id', flat=True)

в связи с этим возникает проблема если у любого моего содержимого нет фильтра фильтров, связанных с ним, то оно не будет включено в это. Поэтому я фильтрую те, которые имеют значение доступа False. Это означает, что у этого содержимого есть фильтр с высоким ручным порядком, который блокирует его для этого конкретного пользователя. Теперь у меня есть список идентификаторов содержимого, которые я могу исключить из всего содержимого. Таким образом, это будет:

contents = Contents.objects.exclude(id__in=blocked_content_list)
Вернуться на верх