最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

Django.aggregate() method giving wrong values - Stack Overflow

matteradmin4PV0评论
class ReportView(AdminOnlyMixin, ListView):
model = homecleaners
template_name = 'home_clean/report/store_list.html'
context_object_name = 'stores'
paginate_by = 20
ordering = ['-id']
valid_statuses = [2, 3, 5]

def get_queryset(self):
    queryset = super().get_queryset()
    search_text = self.request.GET.get('search_text')
    picked_on = self.request.GET.get('picked_on', None)

    if search_text:
        queryset = queryset.filter(store_name__icontains=search_text)
    if picked_on:
        date_range = picked_on.split(' to ')
        start_date = parse_date(date_range[0])
        end_date = parse_date(date_range[1]) if len(date_range) > 1 else None
        date_filter = {'orders__timeslot__date__range': [start_date, end_date]} if end_date else {'orders__timeslot__date': start_date}
        queryset = queryset.filter(**date_filter)

    status_filter = Q(orders__status__in=self.valid_statuses)

    queryset = queryset.prefetch_related('orders').annotate(
        orders_count=Count('orders__id', filter=status_filter),
        subtotal=Sum('orders__subtotal', filter=status_filter),
        store_discount=Sum(
            Case(
                When(Q(orders__promocode__is_store=True) & status_filter, then='orders__discount'),
                default=Value(0),
                output_field=FloatField()
            )
        ),
        admin_discount=Sum(
            Case(
                When(Q(orders__promocode__is_store=False) & status_filter, then='orders__discount'),
                default=Value(0),
                output_field=FloatField()
            )
        ),
        total_sales=Sum(
            F('orders__subtotal') - Case(
                When(Q(orders__promocode__is_store=True), then=F('orders__discount')),
                default=Value(0),
                output_field=FloatField()
            ),
            filter=status_filter
        ),
        commission=Sum(
            (F('orders__subtotal') - Case(
                When(Q(orders__promocode__is_store=True), then=F('orders__discount')),
                default=Value(0),
                output_field=FloatField()
            )) * F('earning_percentage') / 100,
            filter=status_filter
        )
    )

    return queryset.distinct()

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['count'] = context['paginator'].count

    # Calculate store-level aggregates
    status_filter = Q(orders__status__in=self.valid_statuses)
    store_totals = {}
    for store in self.object_list:
        total = store.orders.filter(status__in=self.valid_statuses).aggregate(
            subtotal=Sum('subtotal')
        )['subtotal'] or 0
        store_totals[store.store_name] = total

    print("Store Totals------:", store_totals)
    store_total_aggr = self.object_list.aggregate(all_orders=Sum('orders__subtotal', filter=status_filter, default=0))
    print("Store Total Aggregates---------:", store_total_aggr)
    
    return context




> Store Totals------: {'aminu1': 600.0, 'Golden Touch': 0, 'hm': 100.0,
> 'Silk Hospitality': 0, 'Test clean': 0, 'Razan Hospitality': 0,
> 'Enertech Cleaning': 0, 'Bait Al Karam Hospitality': 0, 'Clean pro':
> 0, 'Dr.Home': 0, 'Dust Away': 0, 'Al Kheesa General Cleaning': 0,
> 'test': 0, 'fresho': 0, 'justmop': 0, 'cleanpro': 0, 'Test Store':500.0}
>  Store Total Aggregates---------: {'all_orders': 300.0}

Here the Store Total Aggregates value of all_orders should be 1200 right but instead im getting 300 why, help me fix this

im not using aggregate just for finding total sum of subtotal i have other criteria also like net_amount , commission, profilt, etcl... im showing finding subtotal only here for the sake of understanding

class HomecleanOrders(models.Model):
user = models.ForeignKey(Customer, on_delete=models.CASCADE, null=True, blank=True)
store = models.ForeignKey(homecleaners, on_delete=models.CASCADE, related_name='orders')
service_area = models.ForeignKey(HomeCleanServiceArea, on_delete=models.SET_NULL, null=True, blank=True)
timeslot = models.ForeignKey(HomecleanSlots, on_delete=models.SET_NULL, null=True)
address = models.ForeignKey(Address, on_delete=models.SET_NULL, null=True, blank=True)
duration = models.IntegerField(default=4)
ref_id = models.UUIDField(default=uuid.uuid4, editable=False, null=True, blank=True)
date = models.DateField(null=True, blank=True)
no_of_cleaners = models.IntegerField()
cleaner_type = models.CharField(max_length=4, choices=CLEANER_TYPES, null=True, blank=True)
material = models.BooleanField()
material_charges = models.FloatField(default=0)
credit_card = models.ForeignKey('customer.CustomerCard', on_delete=models.SET_NULL, null=True, blank=True)
payment_type = models.CharField(choices=PAYMENT_CHOICES, default='COD1', max_length=10)
wallet = models.BooleanField(default=False)
deducted_from_wallet = models.FloatField(default=0)
status = models.IntegerField(choices=STATUS_CHOICES, default=WAITING)
state = models.IntegerField(choices=STATE_CHOICES, null=True, blank=True)
subtotal = models.FloatField(default=0)
grand_total = models.FloatField(default=0)
extra_charges = models.FloatField(default=0)
discount = models.FloatField(default=0)
to_pay = models.FloatField(default=0)
is_paid = models.BooleanField(default=False)
is_refunded = models.BooleanField(default=False)
is_payment_tried = models.BooleanField(default=False)
vendor_confirmed = models.BooleanField(default=False)
promocode = models.ForeignKey(PromoCodeV2, on_delete=models.SET_NULL, null=True, blank=True)
vendor_settled = models.BooleanField(default=False)
cancel_reason = models.TextField(null=True, blank=True)
workers = models.ManyToManyField(HomeCleanWorker, blank=True)
created_on = models.DateTimeField(auto_now_add=True)
invoice_id = models.CharField(max_length=200, null=True, blank=True)
bill_id = models.CharField(max_length=200, null=True, blank=True)

instructions = models.CharField(max_length=255, null=True, blank=True)
voice_instructions = models.FileField(upload_to='voice_instructions', null=True, blank=True)
dont_call = models.BooleanField(default=False)
dont_ring = models.BooleanField(default=False)
leave_at_reception = models.BooleanField(default=False)

def save(self, *args, **kwargs):
    super(HomecleanOrders, self).save(*args, **kwargs)
    self.create_transaction_if_needed()

def create_transaction_if_needed(self):
    """Creates a transaction for the order if it is marked as DONE, payment type is COD, and is paid."""
    if self.is_paid and self.status == DONE and self.payment_type == 'COD1' and not hasattr(self, 'transaction'):
        amount = self.subtotal - (self.discount + self.deducted_from_wallet)
        HCTransaction.objects.create(order=self, amount=amount, store=self.store)

def __str__(self):
    return f'{self.id}-{self.store}-{self.user}'

def process_totals(self, auto_order=False, custom_price=0):
    hours_charge = self.service_area.hours_charge if self.service_area else self.store.hours_charge
    weekday = self.date.strftime("%w")
    price = HCWeekdayOffer.objects.get(vendor=self.store).get_weekday_price(week_num=int(weekday))
    price = hours_charge - price if price and price > 0 else hours_charge
    if auto_order:
        price = custom_price if int(custom_price) > 0 else self.store.recurring_price or hours_charge
    self.subtotal = (self.duration * price) * self.no_of_cleaners + self.extra_charges
    if self.material:
        total_material_charge = self.material_charges * self.no_of_cleaners
        self.subtotal += (self.duration * total_material_charge)
    offer_amount = 0
    if self.promocode:
        is_free_delivery, is_cash_back, offer_amount = self.promocode.get_offer_amount(self.subtotal)
        if is_cash_back:
            offer_amount = 0
    grand_total = self.subtotal - offer_amount
    self.grand_total = grand_total
    self.to_pay = grand_total
    self.discount = offer_amount
    self.save()

def get_cleaner_profit(self):
    a = self.subtotal
    result = a * 0.7
    result_round = round(result, 2)
    return result_round

@cached_property
def order_type(self):
    return 'home_clean'

class homecleaners(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, limit_choices_to={'user_type': 5})
store_name = models.CharField(max_length=88)
store_name_arabic = models.CharField(max_length=88)
description = models.CharField(max_length=150, null=True, blank=True)
description_arabic = models.CharField(max_length=150, null=True, blank=True)
cleaner_type = models.CharField(max_length=4, choices=CLEANER_TYPES, default=BOTH)
earning_percentage = models.FloatField(default=30)
image = models.ImageField(upload_to='homecleaners/logos')
address = models.TextField()
Post a comment

comment list (0)

  1. No comments so far