Как отфильтровать поле many2many с помощью другого many2many?

В моем Django есть следующая модель:

class Filter(models.Model):
    min_price = models.PositiveIntegerField(null=False, blank=False)
    max_price = models.PositiveIntegerField(null=False, blank=False)
    trait = models.ManyToManyField(Trait, null=True, blank=True)

class Flat(models.Model):
    living_area = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True, db_index=True)
    trait = models.ManyToManyField(Trait)

class Trait(models.Model):
    name = models.CharField(max_length=255, blank=False, null=False, db_index=True)

В моем случае trait может быть, например, лифтом. Если есть связь между Flat и Trait(name="Elevator"), то я могу предположить, что у Flat есть лифт.

Я хочу сделать поиск квартир по признакам - признаки из квартиры и признаки из фильтра должны быть одинаковыми.

Я сделал примерно следующее:

filte_obj = Filter.objects.get(pk=pk)
flat = Flat.objects.filter(trait__id__in=[x.id for x in filter_obj.trait.all()])

К сожалению, это не работает так, как я хочу. Я хочу видеть только квартиры, Traits QuerySet которых совпадает с Traits QuerySet фильтра

Как я могу это сделать?

Я решил свою проблему, используя аннотации моделей django:

filter_obj = Filter.objects.get(pk=pk)
traits_list = [x.id for x in filter_obj.trait.all()]
offers = Offer.objects \
    .filter(flat__living_area__range=(filter_obj.min_area, filter_obj.max_area),
            flat__trait__id__in=traits_list) \
    .annotate(num_traits=Count('flat__trait')).filter(num_traits=filter_obj.trait.count())

Дополнительная информация:

Django filter by many to many with exact same query

Вернуться на верх