django - get first record for each day - django

I have a model Sales with:
Saler
Product sold
Date
I would like to get the first sale for each date and for each saler, how can I do that?
Thanks

Considering the model Posted in the question, the Django ORM query will be:
first_sale = Sales.objects.order_by("Saler", "Date").distinct("Saler")

Not tested, but I would try (I assumed the field for the date of the sale is named sale_date, and is of type Datetime):
first_sale = Sales.objects.filter(saler=the_saler, sale_date__date=datetime.date(2021, 05, 19)).order_by('sale_date').first()
filter will restrict the search to a given saler (the_saler), and to a given day (see the __date expression: https://docs.djangoproject.com/fr/3.1/ref/models/querysets/#date)
order_by and first will give you the first of the day.

Related

Group objects by dates

clicks = SellerClick.objects.extra({'date' : "date(timestamp)"}).values('date').annotate(count=Count('timestamp'))
The model has a datetime field called timestamp that was are using. I first, convert the datetime field to just a date field. Then the rest is guessing. I need to group by, and then count how many objects are of each date.
So the desired result would be a date, then a count, based on how many objects have that date in the timestamp field.
I prefer to use annotate over extra
from django.db.models.expressions import RawSQL
SellerClick.objects.annotate(
date=RawSQL('date(date_joined)',[]),
).values('date').annotate(count=Count('date')))
You've got everything but an initial queryset there. The extra sql you're passing doesn't include a select so you need to give it something to act on.
clicks = SellerClick.objects.all()
.extra({'date' : "date(timestamp)"})
.values('date')
.annotate(count=Count('timestamp'))
Ref: StackOverflow: Count number of records by date in Django

Grouping Django model entries by day using its datetime field

I'm working with an Article like model that has a DateTimeField(auto_now_add=True) to capture the publication date (pub_date). This looks something like the following:
class Article(models.Model):
text = models.TextField()
pub_date = models.DateTimeField(auto_now_add=True)
I want to do a query that counts how many article posts or entries have been added per day. In other words, I want to query the entries and group them by day (and eventually month, hour, second, etc.). This would look something like the following in the SQLite shell:
select pub_date, count(id) from "myapp_article"
where id = 1
group by strftime("%d", pub_date)
;
Which returns something like:
2012-03-07 18:08:57.456761|5
2012-03-08 18:08:57.456761|9
2012-03-09 18:08:57.456761|1
I can't seem to figure out how to get that result from a Django QuerySet. I am aware of how to get a similar result using itertools.groupby, but that isn't possible in this situation (explanation to follow).
The end result of this query will be used in a graph showing the number of posts per day. I'm attempting to use the Django Chartit package to achieve this goal. Chartit puts a constraint on the data source (DataPool). The source must be a Model, Manager, or QuerySet, so using itertools.groupby is not an option as far as I can tell.
So the question is... How do I group or aggregate the entries by day and end up with a QuerySet object?
Create an extra field that only store date data(not time) and annotate with Count:
Article.objects.extra({'published':"date(pub_date)"}).values('published').annotate(count=Count('id'))
Result will be:
published,count
2012-03-07,5
2012-03-08,9
2012-03-09,1

query django date

In ,models i have
class pick:
t1 =models.DateTimeField(auto_now_add=True)
In views.
The date variable is in the format s="2010-01-01"
How o query the for the date now
pick.objects.filter(t1=date(s))
datetime.date() expected arguments are datetime.date(year, month, day), so creating a date object with s won't work. But you can use the date string directly in filter like
picks_at_date = pick.objects.filter(t1=s)
or when you try to find anything before or after that date
picks_before_date = pick.objects.filter(t1__lt=s)
or
picks_after_date = pick.objects.filter(t1__gt=s).
Django's "Making queries" Docs at Retrieving specific objects with filters has some good examples on making queries with date fields as well.

Django: Count objects in a particular month

I have this model:
class Person(models.Model):
city = models.CharField(max_length=20, blank=True)
added_date = models.DateField(default=datetime.date.today)
I want to create a template/view that has a table of months and the number of people added that month (ie, 5 in january, 10 in february, 8 in march, etc.). I have a similar table for all the people from a each city using:
cities = Patient.objects.values('city').annotate(city_count=Count('city')).order_by('-city_count')
I don't know how to do that for my months table. I could filter for a particular month, then count all. But then I'd need to run that through a loop over every month, which would be multiple database hits. I don't want to do that.
Is there a way to do this without writing sql and just using django's api?
Its a very old thread, but i guess I'll answer in case someone else ended up here looking for a solution.
The solution is for Django 1.10+ using the ExtractMonth function, for more detail visit official documentation
First you have to import ExtractMonth, like
from django.db.models.functions import ExtractMonth
Then using your Persons model, the code will be like this
personsMonthlyData = Person.objects.annotate(month=ExtractMonth('added_date')).values('month').annotate(count=Count('id')).order_by('month')
personsMonthlyData will output something like this
[{month: 1, count: 3}, {month: 2: count: 1}]
where month represent the month number e.g. 1 for January and 2 for February and the count against each month is assigned to the count item.
I hope this helps.
The fact that most DBs have such a perfect way of doing this with a GROUP BY query that has no analog in Django AFAIK would lead me to drop into SQL to do this. I did a google search for "django sql" and turned up this post by Doug Hellman on this exact problem: http://blog.doughellmann.com/2007/12/using-raw-sql-in-django.html. I would use that as a starting point for getting your month counts into Django.

django: time range based aggregate query

I have the following models, Art and ArtScore:
class Art(models.Model):
title = models.CharField()
class ArtScore(models.Model):
art = models.ForeignKey(Art)
date = models.DateField(auto_now_add = True)
amount = models.IntegerField()
Certain user actions results in an ArtScore entry, for instance whenever you click 'I like this art', I save a certain amount of ArtScore for that Art.
Now I'm trying to show a page for 'most popular this week', so I need a query aggregating only ArtScore amounts for that time range.
I built the below query but it's flawed...
popular = Art.objects.filter(
artscore__date__range=(weekago, today)
).annotate(
score=Sum('artscore__amount')
).order_by('-score')
... because it only excludes Art that doesn't have an ArtScore record in the date range, but does not exclude the ArtScore records outside the date range.
Any pointers how to accomplish this would be appreciated!
Thanks,
Martin
it looks like according to this:
http://docs.djangoproject.com/en/dev/topics/db/aggregation/#order-of-annotate-and-filter-clauses what you have should do what you want. is the documentation wrong? bug maybe?
"the second query will only include
good books in the annotated count."
in regards to:
>>> Publisher.objects.filter(book__rating__gt=3.0).annotate(num_books=Count('book'))
change this to your query (forget about the order for now):
Art.objects.filter(
artscore__date__range=(weekago, today)
).annotate(
score=Sum('artscore__amount')
)
now we can say
"the query will only include artscores
in the date range in the annotated
sum."