Подсчет аннотаций Django для другого набора запросов

Модели:

class Regions(models.Model):
    name = models.CharField(max_length=255, unique=True)


class Owners(models.Model):
    name = models.CharField(max_length=255, null=False, unique=True)
    url = models.URLField(null=True)


class Lands(models.Model):
    region = models.ForeignKey(Regions, on_delete=models.CASCADE)
    owner = models.ForeignKey(Owners, on_delete=models.PROTECT, null=True)
    description = models.TextField(max_length=2000, null=True)


class LandChangeHistory(models.Model):
    land = models.ForeignKey(Lands, on_delete=models.CASCADE, null=False, related_name='lands')
    price = models.IntegerField()
    size = models.IntegerField()
    date_added = models.DateField(auto_now_add=True)
<
lands_in_region = Lands.objects.values('region__name').annotate(count=Count('region_id'))

возвращает, например:

{'region__name': 'New York', 'count': 3}, {'region__name': 'Chicago', 'count': 2}

.

Во втором наборе вопросов мне нужно подсчитать количество земель, доступных в регионе. Но вместо реального количества я всегда получаю count = 1. Как их объединить? Я почти уверен, что могу сделать это в raw sql, объединив две таблицы по полю "region__id", но не знаю, как это сделать в django orm.

f = LandFilter(request.GET, queryset=LandChangeHistory.objects.all()
                           .select_related('land', 'land__region', 'land__owner')
                           .annotate(usd_per_size=ExpressionWrapper(F('price') * 1.0 / F('size'), output_field=FloatField(max_length=3)))
                           .annotate(count=Count('land__region_id'))
                           )

Например. Если он возвращает:

<<<1><1>> земля1 | $100 | 100м2 | Нью-Йорк

.

земля2 | $105 | 105м2 | Нью-Йорк

земля3 | $102 | 102м2 | Чикаго

Мне нужен еще 1 столбец, который подсчитывает для каждой земли, сколько там Нью-Йорков и Чикаго

<<<1><2>> земля1 | $100 | 100м2 | Нью-Йорк | 2

.

land2 | $105 | 105m2 | New York | 2

.

земля3 | $102 | 102м2 | Чикаго | 1

.

Это помогло мне. Надеюсь, кому-нибудь поможет.

Сначала я попытался просто вызвать метод Count() сразу после фильтра, но это ломает запрос, так как он пытается получить данные из БД немедленно. Но это был правильный ход мыслей, поэтому я добавил аннотацию count и выбрал ее, и все заработало.

 f = LandFilter(request.GET, queryset=LandChangeHistory.objects.all()
 .select_related('land', 'land__region', 'land__owner')
 .annotate(usd_per_size=ExpressionWrapper(F('price') * 1.0 / F('size'), output_field=FloatField(max_length=3)))        
    
 .annotate(count=Subquery(
                     Lands.objects.filter(region_id=OuterRef('land__region_id'))
                     .values('region_id')
                     .annotate(count=Count('pk'))
                     .values('count')))
                     )
Вернуться на верх