I am using a RAW SQL query to get the record of each week's sale and then sum it up and show it on the web page. Here's my query:
sales = addCustomer.objects.raw("SELECT SUM(productPrice) FROM cms_addcustomer WHERE date <= %s and date >= %s", [startdate, weekDate])
Already using the datetime library to get the date and everything is working fine on this end.
However, when I try to display the result I get this message on my webpage:
Total Sales: Rs.<RawQuerySet: SELECT
SUM(productPrice) FROM cms_addcustomer WHERE
date <= 2020-07-29 and date >= 2020-07-23>
As also shown in this screenshot
I just want to display the sum of the Sales on my webpage but I am not sure how to do it.
addCustomer Model:
from django.db import models
from datetime import date
class addCustomer(models.Model):
customerName = models.CharField(max_length=100)
productName = models.CharField(max_length=100)
productPrice = models.IntegerField()
date = models.DateField(default=date.today)
commission = models.IntegerField()
I have read most of the answers on Stack Overflow but I was unable to understand them as I am complete beginner. How can I fix this?
You can create a query with .aggregate(…) [Django-doc]:
from django.db.models import Sum
total = addCustomer.objects.filter(
date__range=(weekDate, startDate)
).aggregate(
total_productprice=Sum('productPrice')
)['total_productprice']
here total will thus retrieve the sum of the productPrice values in the range.
For your date field, you might want to use a db_index=True [Django-doc] to boost searching the records. Furthermore you might want to use auto_now_add=True [Django-doc], this will not only set the field value to the current date, but also make the field non-editable by default:
class addCustomer(models.Model):
customerName = models.CharField(max_length=100)
productName = models.CharField(max_length=100)
productPrice = models.IntegerField()
date = models.DateField(auto_now_add=True, db_index=True)
commission = models.IntegerField()
Note: normally the name of the fields in a Django model are written in snake_case, not PerlCase, so it should be: product_price instead of productPrice.
Related
I'm using Django. i'm trying to write query according to the top rated products. i have product table. as you can see below.
class Product(models.Model):
user = models.ForeignKey(User, verbose_name=_("Owner"), on_delete=models.CASCADE)
name = models.CharField(_("Name"), max_length=150,null=True)
average_rating =models.DecimalField(_("average rating"), max_digits=10, decimal_places=2,null=True,blank=True)
total_reviews = models.IntegerField(_("total reviews "),default=0,null=True,blank=True)
is_remove = models.BooleanField(_("Remove"), default=False)
create_time = models.DateTimeField(_("Create time"), default=timezone.now)
Now i want to get all objects which have highest average rating and total count.
I have tried many things below. but none of them worked.
1 -
def get_all_top_rated_products(self):
query = self.filter(is_remove=False).order_by("total_reviews","average_rating")
print(query)
return query
2
def get_all_top_rated_products(self):
query = self.filter(is_remove=False).aggregate(Max('average_rating'),Max('total_reviews'))
print(query)
return query
You should order in descending order, you can do this by prefixing the fieldname with a minus (-):
def get_all_top_rated_products(self):
return self.filter(is_remove=False).order_by(
'-average_rating', '-total_reviews'
)
I am a complete beginner in django. I'm stuck with this problem and can't seem to find a solution to query it properly. (T-T)
django ver : 1.11 python ver : 2.7
Let's say we have 3 models:
class Coupon(models.Model):
pass
class CouponApplication(models.Model):
"""
Track application of a coupon.
"""
coupon = models.ForeignKey(Coupon, related_name="applications",verbose_name=("Coupon"))
order = models.ForeignKey(Order, verbose_name=("Order")related_name='order_coupon_applications')
class Order(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='user_order', verbose_name="Customer")
order_date = models.DateTimeField(verbose_name='Order Date and Time')
shop = models.ForeignKey(Location, null=True, on_delete=models.SET_NULL)
class OrderItem(models.Model):
order = models.ForeignKey(Order, related_name='order_items')
order_type = models.CharField('Type', choices=ORDER_ITEM_TYPE, default=INVENTORY)
buy_get_discount = models.DecimalField(_('Buy & Get Discount'))
sub_total = models.DecimalField(_('Sub Total'), max_digits=18, decimal_places=2)
Now for each coupon, I need to find the gross sales of the products, sold using it. I am finding it pretty hard to write a query for the same because I need to annotate the sum of subtotal of order item to each coupon object and I guess this requires joining coupon application, order item and order table .
So far I've written this much:
buy_gets_gross_sales = OrderItem.objects.filter(order_type=OrderItem.INVENTORY,
buy_get_discount__gt=0,
order_id__in=CouponApplication.objects.filter(coupon=OuterRef('pk'),
).values('order')
).values('order_type')
gross_sales = buy_gets_gross_sales.annotate(gross=Sum('sub_total')).values('gross')
gross_Sales_report = Coupon.objects.annotate(
total_gross_sales =Round(Coalesce(Subquery(gross_sales, output_field=models.DecimalField()), Value(0))) ,)
i know this wont work, but i need something of this sort. it is already throwing some errors saying the inner query need to be used in a subquery or something.I need the aggregate value to be annotated with the coupon objects.
I've added the raw sql query below too:
'(select coalesce(sum(sub_total),0) from order_orderitem'
' where order_type=%(order_type)s and buy_get_discount > %(discount)s'
'and order_id in (select distinct(order_id) from coupon_couponapplication where coupon_id=t1.id '
'{0}'
'and date_created between %(start)s and %(end)s' # comment this line to remove date filter
')) '
Here t1 is Coupon model.
Help, I am pretty sure it is possible to write django query for this one, but as I said I am not able to figure it out.
Please help me to find a solution, thanks in advance. <3
I'm trying to build an Inventory Model for a Django App that handles the sale of seeds. Seeds are stored and sold in packs of 3, 5, or 10 seeds of a single variety (for example: 3 pack of mustard seeds).
I want to add x amount of products to inventory with a price for each entry, and sell that product at that price for as long as that entry has items left(quantity field > 0) even if later entries have been made for the same product and presentation but at a different price, so i have the following model:
class Product(models.Model):
name = models.CharField(max_length=100)
class Presentation(models.Model):
seed_qty = models.IntegerField()
class Stock(models.Model):
date = models.DateField(auto_now=True)
quantity = models.IntegerField()
product = models.ForeignKey(Product, on_delete=models.CASCADE)
presentation = models.ForeignKey(Presentation, on_delete=models.CASCADE)
cost = models.FloatField(null=True, blank=True)
sell_price = models.FloatField(null=True, blank=True)
I'm wondering if I should actually relate Product and Stock with a ManyToMany field through a GeneralEntry intermediate model in which I'd store date_added, presentation and cost/price.
My issue is that when I add multiple Stock entries for the same product and presentation, I can't seem to query the earliest prices for each available (quantity>0) stock entry for each product.
What I've tried so far has been:
stock = Stock.objects.filter(quantity__gt=0).order_by('-date')
stock = stock.annotate(min_date=Min('date')).filter(date=min_date)
But that returns that max_date isn't defined.
Any ideas on how to query or rearrange this model ?
Thanks!
*** UPDATE : I wasn't using F() function from django.db.models.
Doing it like this works:
stock = Stock.objects.filter(quantity__gt=0).order_by('-date')
stock = stock.annotate(min_date=Min('date')).filter(date=F('min_date'))
Turns out I wasn't using F() function from django.db.models.
Doing it like this works:
stock = Stock.objects.filter(quantity__gt=0).order_by('-date')
stock = stock.annotate(min_date=Min('date')).filter(date=F('min_date'))
I have something like this:
class Car(models.Model):
model = models.CharField(max_length=200)
brand = models.CharField(max_length=100)
status = models.ManyToMany(Status)
class Status(models.Model):
name = models.CharField(max_length=40)
date = models.DateTimeField('Status creation date')
How can I query all the cars where their last status (most recent) is REPAIRED for instance? Is this achievable in just one query?
from django.db.models import Max
cars = Car.objects.annotate(Max('status__date')).filter(status__name='REPAIRED').distinct()
You may read the Django examples for Many to Many relationships.
I have models called Stores and SaleItems which look some what like this.
class Stores(models.Model):
name = models.CharField(unique=True, max_length=20)
class SaleItems(models.Model):
sale_by = models.ForeignKey(Stores)
start_date = models.DateTimeField()
end_date = models.DateTimeField()
So I need to retrieve sale items based on the following conditions.
If its not my store, then leave out items having start_date greater than today and end_date lesser than today.
If its my store, then get items irrespective of start_date and end_date.
So in my views.py, this is how far I have come up.
class SaleItemsView(viewsets.ModelViewSet):
querys = SaleItems.objects.all()
def get_queryset(self):
#get my store id
store_id = self.request.query_params.get('store_id')
querys = SaleItems.objects\
.exclude(store__ne=store_id, end_date__lt=timezone.now())\
.exclude(store__ne=store_id, start_date__gt=timezone.now())
return querys
But it seems django doesn't have not equal operator any more. Is there any other way I can achieve this?
I think you would combine the records for each of your conditions using Qobjects, then do distinct() to remove duplicates:
now = timezone.now()
items_within_date_range = Q(start_date__lte=today, end_date__gte=today)
curr_store_items = Q(store=store_id)
result = SaleItems.objects.filter(items_within_date_range|curr_store_items).distinct()
The first query would get all items within time range for both your store and other stores, second query would get all items for your store, then combine then would get everything.