django extract only year from date time in queryset - python

I have a purchases table with a column datatime. I would like to select all purchases I have done in the current year. bellow is my code but is not working!
import datetime
today = datetime.date.today()
year = Purchases.objects.filter(date__year = today.year)
I expect the year should be 2018 extracted from 2018-04-12

You can use ExtractYear function, here is example:
from django.db.models.functions import ExtractYear
qs = Purchases.objects.annotate(year=ExtractYear('date')).filter(year = today.year)

While querying, we can get year from model field of type DateField as fieldname__year (for comparision). If we have a field named 'purchase_date' in our model, we can filter data for a particular year as:
MyModel.objects.filter(purchase_date__year=targetyear)
In your case, if the column name is datatime. You can get the purchases done in current year as:
import datetime
today = datetime.date.today()
purchases = Purchases.objects.filter(datatime__year=today.year)

Related

MongoEngine filter for date column

I am trying to use MongoEngine to apply a filter on a mongodb collection called Employees. The filter is based on country, city and join_date.
The filter condition is that the number of months obtained by subtracting join_date from today's date should be a minimum of "x" months, where x is a setting value. So, for example, if x is 18 months, I need to find all employees whose join_date was a minimum of 18 months prior to today's date.
I am trying to achieve this by calling the filter() method, but I'm unable to figure out how to do that.
matching_records = Employees.objects(
country=rule.country,
city=rule.city) \
.filter(relativedelta.relativedelta(datetime.datetime.now, join_date).months > 18)
I get an error, "name join_date is not defined". I am unable to figure out how to get the filter to work. Please help.
You need to use the lte (less than or equal) or gte (greater than or equal) operators like this:
from datetime import datetime, timedelta
import dateutil.relativedelta
from mongoengine import *
connect()
now = datetime.utcnow()
yesterday = now - dateutil.relativedelta.relativedelta(days=5)
past = now - dateutil.relativedelta.relativedelta(months=20)
class TestDate(Document):
dt = DateTimeField()
# Saving 3 objects to verify the query works
TestDate(dt=now).save()
TestDate(dt=yesterday).save()
TestDate(dt=past).save()
TestDate.objects(dt__lte=now - dateutil.relativedelta.relativedelta(months=18)) # return TestData associated with `past`
TestDate.objects(dt__gte=now - dateutil.relativedelta.relativedelta(months=18)) # return TestData associated with `now` and `yesterday`

How to update exisiting date field in django using existing days field?

I want to update existing date field in django using existing days field in the same table.
For example
class Sample(models.Model):
notify_status = models.BooleanField(default=0)
next_date = models.DateField(blank=True, null=True)
days = models.IntegerField(blank=True, null=True)
Now I want to add days to next_date where next_date is less than todays date.
I have tried this:
import datetime
from django.db.models import F
Sample.objects.filter(next_date__lt=today).update(next_date=F('next_date')+datetime.timedelta(days=F('days')))
But its not working.
Here is the output
Something went wrong in period_retrack.py: unsupported type for timedelta days component: F
Expected Output
I want next_date to be increased by the number of days in the same table for every row where next_date is less than current_date i.e, today's date
You can cast the days field value to an interval at the database level:
import datetime
from django.db.models import CharField, DurationField, F, Value
from django.db.models.functions import Cast, Concat
Sample.objects.filter(next_date__lt=today).update(
next_date=F("next_date")
+ Cast(
Concat("days", Value(" days"), output_field=CharField()),
output_field=DurationField(),
)
)
Notice that I'm doing the cast in 2 steps:
Concatenate the value with the " days" suffix (e.g. "1 days")
Cast this string to a duration
This would work with Postgres, I'm not sure about other databases.

Django: Why Filtering By Year Works, But Not Month and Day?

I have a simple datetime field named date. Stores dates and time like this: 2015-07-04 01:40:00+00:00.
When I run
today = datetime.datetime.now().today()
x = game.objects.filter(date__year=today.year)
It works, however if i run
today = datetime.datetime.now().today()
x = game.objects.filter(date__month=today.month)
I get an empty list.
Current month is July. If you filter by the year part of the date being equal to current month, then you search for records being in the year of 07 AD. I believe you do not have such records. You need to filter by month of the date if you want to filter by month.

python queryset date filter not change date to current date

My queryset filter did return the correct filtered data on the first date that I wrote the code but after that the date is stuck to that specific date and does not bring up the filtered information based on the current date.
What am I doing wrong?
today = datetime.date.today()
todaydate = today
url(r'^maanta/', ListView.as_view(
queryset= Article.objects.filter(pub_date__startswith=todaydate),
template_name="myarticle.html")),
If you assign the date like you did on the module level, it is only evaluated once.
The trick is to use a lambda function:
todaydate = lambda: datetime.date.today()
And to adjust your lookup to:
Article.objects.filter(pub_date__startswith=todaydate())

Django Group By Weekday?

I'm using Django 1.5.1, Python 3.3.x, and can't use raw queries for this.
Is there a way to get a QuerySet grouped by weekday, for a QuerySet that uses a date __range filter? I'm trying to group results by weekday, for a query that ranges between any two dates (could be as much as a year apart). I know how to get rows that match a weekday, but that would require pounding the DB with 7 queries just to find out the data for each weekday.
I've been trying to figure this out for a couple hours by trying different tweaks with the __week_day filter, but nothing's working. Even Googling doesn't help, which makes me wonder if this is even possible. Any Django guru's here know how, if it is possible to do?
Since extra is deprecated, here is a new way of grouping on the day of the week using ExtractDayOfWeek.
from django.db.models.functions import ExtractWeekDay
YourObjects.objects
.annotate(weekday=ExtractWeekDay('timestamp'))
.values('weekday')
.annotate(count=Count('id'))
.values('weekday', 'count')
This will return a result like:
[{'weekday': 1, 'count': 534}, {'weekday': 2, 'count': 574},.......}
It is also important to note that 1 = Sunday and Saturday = 7
Well man I did an algorithm this one brings you all the records since the beginning of the week (Monday) until today
for example if you have a model like this in your app:
from django.db import models
class x(models.Model):
date = models.DateField()
from datetime import datetime
from myapp.models import x
start_date = datetime.date(datetime.now())
week = start_date.isocalendar()[1]
day_week =start_date.isoweekday()
days_quited = 0
less_days = day_week
while less_days != 1:
days_quited += 1
less_days -= 1
week_begin = datetime.date(datetime(start_date.year,start_date.month,start_date.day-days_quited))
records = x.objects.filter(date__range=(week_begin, datetime.date(datetime.now())))
And if you add some records in the admin with a range between June 17 (Monday) and June 22 (today) you will see all those records, and if you add more records with the date of tomorrow for example or with the date of the next Monday you will not see those records.
If you want the records of other week unntil now you only have to put this:
start_date = datetime.date(datetime(year, month, day))
records = x.objects.filter(date__range=(week_begin, datetime.date(datetime.now())))
Hope this helps! :D
You need to add an extra weekday field to the selection, then group by that in the sum or average aggregation. Note that this becomes a database specific query, because the 'extra' notation becomes passed through to the DB select statement.
Given the model:
class x(models.Model):
date = models.DateField()
value = models.FloatField()
Then, for mysql, with a mapping of the ODBC weekday to the python datetime weekday:
x.objects.extra(select={'weekday':"MOD(dayofweek(date)+5,7)"}).values('weekday').annotate(weekday_value=Avg('value'), weekday_value_std=StdDev('value'))
Note that if you do not need to convert the MySql ODBC weekday (1 = Sunday, 2 = Monday...) to python weekday (Monday is 0 and Sunday is 6), then you do not need to do the modulo.
For model like this:
class A(models.Model):
date = models.DateField()
value = models.FloatField()
You can use query:
weekday = {"w": """strftime('%%w', date)"""}
qs = A.objects.extra(select=weekday).values('w').annotate(stat = Sum("value")).order_by()

Categories