Подсчет аннотаций 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'))) )