admin管理员组

文章数量:1026989

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()
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()

本文标签: Djangoaggregate() method giving wrong valuesStack Overflow