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.
Related
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.
So I am using a DateField for displaying the date. Which when passed to a template using contexts, renders in the format Nov. 4, 2018
Now there are multiple entries of such dates in the database. And I want to filter on the basis of string of the date actually shown. i.e when I type in Nov 4, or nov 4 or NOV 4 in my search input field, it should show the matched result. More like a substring match.
Now the only problem is that i do not know how to convert my_model.date field in to Nov. 4, 2018.
str(my_model.date) returns 2016-11-04 and I do not want to parse this with month_number-to-month_name map
I think, any of the two solutions should work.
1) Django filters that allow me to do so.
2) converting my_model.date into Nov. 4, 2018 string
Help please, been stuck on this forever now
Because you specifically mention rendering the date in a template, I'm not sure if the search operation you're referring to is a front-end, user-facing thing or a backend database query.
If you want to convert my_model.date to a prettier string before sending it to the template before display, you can process it in your view with strptime - this will give you the control that you're missing with the str wrapper: https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior While there are template tags that can do this for you as well, doing it in your view is faster and better.
If this is a DB query, then remember that you can filter date objects by their attributes. For example, to get all instances created on November 11th, 2011:
MyModel.objects.filter(
date__day = 11,
date__month = 11,
date__year = 2018
)
Note the double underscores.
Responding to your comment, now that I better understand your goal:
Date fields do not store their more "verbose" date information in a queryable spot. If you want to be able to query for things like "Nov" instead of 11 then you'll need to add another attribute (or attributes) to your model to propagate that computed data into queryable containers.
If it were me, I would do this within my_model:
from datetime import date
...
rawDate = models.DateField(...) #your current date field
formatted_month = models.CharField(...)
formatted_day = models.IntegerField(...)
formatted_year = models.IntegerField(...)
...
def save(self):
self.formatted_month = date.strftime(self.rawDate, '%b')
self.formatted_day = date.strftime(self.rawDate, '%d')
self.formatted_year = date.strftime(self.rawDate, '%Y')
super().save()
Now you can perform your NOV/nov/Nov lookup like so:
MyModel.objects.filter(
formatted_month__iexact = 'Nov'
)
This still requires you to split the month and day in your search term before hitting the database. If you wanted to squash these down a bit, you could instead store all of the formatted date info in a single field:
formatted_date = models.CharField(...)
...
def save(self):
self.formatted_date = date.strftime(self.rawDate, '%b %d %Y')
Then if your query looks like "NOV 4", you could do:
MyModel.objects.filter(formatted_date__icontains='NOV 4')
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
I have used this query in my view..
temp2=transaction.objects.filter(user_id=client_obj,Date_of_trans.date()=rec_var1)[0].Trans_Amount
I need to compare a datetime field present in my model named Date_of_trans to a variable received from user but the code is not working... what query should be written?
This is basically a sql query. So you should think like that. How can you do this in sql. I mean what condition will you apply in sql. For finding records of particular date with datetime field you should check records between start of the day to end of the day.
try this
from datetime import datetime, time
temp2=transaction.objects.filter(user_id=client_obj,Date_of_trans>datetime.combine(rec_var1, time(0,0,0)), Date_of_trans <= datetime.combine(rec_var1, time(23,59,59)) )[0].Trans_Amount
The above code is written taking into consideration that rec_var1 is a date() object.
Here you check all transactions between start of the day, till end of the day. I think this will resolve your problem.
I've use datetime.combine function which combines date and time object to form datetime object which is required here.
Thanks
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