Django QuerySet для подсчета элементов для каждого отдельного поля в любом месяце, включая значение 0 - PullRequest
0 голосов
/ 23 октября 2018
#models.py
class Orders(models.Model):
    orderid = models.IntegerField(db_column='orderID', primary_key=True) 
    pickupdate = models.DateField(db_column='pickupDate', blank=True, null=True)  
    pickupstore = models.ForeignKey(Branch, models.DO_NOTHING, db_column='pickupStore', blank=True, null=True,related_name = 'pickupstore')  

class Branch(models.Model):
    branchid = models.IntegerField(db_column='branchID', primary_key=True)  # Field name made lowercase.
    city = models.CharField(max_length=45, blank=True, null=True)

Поле пикапа в модели Класса заказов относится к модели класса филиала.

Я хотел бы подсчитать количество пикапов для всех магазинов (филиалов) в любом месяце, в том числе, когда магазины (филиалы)) иметь 0 пикапов в этом конкретном месяце

Это мое решение для подсчета количества или пикапов во всех магазинах (филиалы в январе 2006 года, однако в него не входят магазины, в которых 0 заказов

branchs = Orders.objects.all().select_related('pickupstore').values('pickupstore__city').filter(pickupdate__year = 2006, pickupdate__month = 1).annotate(num=Count('pickupstore__city')).order_by('pickupstore__city')
branchs = branchs.values('pickupstore__city').filter(pickupdate__year = year, pickupdate__month = month)
branchs = branchs.annotate(num=Count('pickupstore__city')).order_by('pickupstore__city')

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Вы должны основывать свой фильтр на ветви, так как вы хотите, чтобы все ветви, даже те, у которых нет заказов для ваших фильтров, поэтому вам нужно левое внешнее объединение.Есть несколько способов сделать это, но для вашего случая сработает следующее.

branches_with_orders= Branch.objects.filter(pickupstore__pickupdate__year=2006, pickupstore__pickupdate__month=1).annotate(num=Count('city'))

branches_without_orders = Branch.objects.exclude(pk__in=branches_with_orders).extra(select={'num': 0}).values('city','num')

all_branches = list(branches_without_orders) + list(branches_with_orders.values('city','num'))

print all_branches

>>> [{'city': u'A', 'num': 0}, {'city': u'B', 'num': 0}, {'city': u'C','num': 4}]
0 голосов
/ 23 октября 2018

Попробуйте сначала аннотировать (), а затем отфильтровать по нему:

pickup_branch = Orders.objects.all().select_related('pickupstore').annotate(num=Count('pickupstore__city')).values('pickupstore__city').filter(pickupdate__year = 2006, pickupdate__month = 1).order_by('pickupstore__city')

, если это не сработает, попробуйте следующее:

all_branch = Orders.objects.all().select_related('pickupstore')
pickup_branch = Orders.objects.all().select_related('pickupstore').values('pickupstore__city').filter(pickupdate__year = 2006, pickupdate__month = 1).annotate(num=Count('pickupstore__city')).order_by('pickupstore__city')    
zero_pickup_branch = [branch for branch in all_branch if not branch in pickup_branch]

это даст вам ветви с 0 подборами
тогда вы можете просто поставить для них значения 0.

...