Как отфильтровать поле 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())
Дополнительная информация: