I am trying to query datetime field in django like the following:
http://127.0.0.1:8000/mr-check/?cname=4&date=2021-09-13+00:09
and views:
cname = request.GET['cname']
date = request.GET['date']
# try:
items = MaterialRequest.objects.filter(owner=cname).filter(delivery_required_on=d)
models:
delivery_required_on = models.DateTimeField(default=datetime.now)
now obviously I don't have an exact instance with 2021-09-13+00:09 but I have instances for the same date, how do I query a datetime field with just date?
You can use the date field lookup. This casts the value as a date.
MaterialRequest.objects.filter(owner=cname).filter(delivery_required_on__date=d)
Also allows chaining additional field lookup, such as gte:
MaterialRequest.objects.filter(owner=cname).filter(delivery_required_on__date__gte=d)
Related
class Customer(models.Model):
name = models.CharField(max_length=200)
# ..
class CustomerTicket(models.Model):
customer = models.OneToOneField(Customer)
date = models.DateTimeField(auto_now_add=True)
# ..
I want to query all customers. And, adding for each customer its ticket if it has one in the date range - so I will get the ticket object only if it is in the given date range, otherwise the ticket field would be null.
Try this:
from django.db import models
customers = Customer.objects.select_related('customerticket').annotate(
ticket=models.Case(models.When(models.Q(customerticket__date__gt=date1) & models.Q(customerticket__date__lt=date2), then=models.F('customerticket')))
)
And you will get ticket as a computed field. Note that when referencing relational fields such as ForeignKey or OneToOneField, F() returns the primary key value rather than a model instance, which means your ticket field will have value of the primary key.
To get customers with related tickets with one query you can use select_related. To make complex condition you can use Q
from django.db.models import Q
Customer.objects.select_related('customerticket').filter(Q(customerticket__date__range=["2018-04-11", "2018-04-12"]) | Q(customerticket__isnull=True))
This will filter data by customerticket date.
Use queryset.filter:
from django.utils import timezone
Customer.objects.exclude(customerticket=None).filter(customerticket__date=timezone.now())
How do I go about filtering a date time field with just a Date field.
With the model and filter below
http://localhost:8020/applications/?created=19-07-2017 returns an empty queryset even with records which have date created=19-07-2017 (The created date of the record in datetime
IN MY MODELS.PY
Class Application(models.Model):
created = models.DateTimeField(auto_now=False, auto_now_add=True)
IN MY FILTERS.PY
import django_filters
class ApplicationFilter(django_filters.FilterSet)
created = django_filters.DateTimeFilter( label='Created')
class Meta:
model = Application
fields = ['created']
Using contains works.
Use DateFilter instead and specify the date format
created=django_filters.DateFilter(input_formats=['%Y-%m-%d','%d-%m-%Y'],lookup_expr='icontains'
use contains
created = django_filters.DateTimeFilter(name='created',lookup_expr='contains')
maybe also need to change the dateformat , yyyy-mm-dd
in your filters.py write this:
import django_filters
class ApplicationFilter(django_filters.FilterSet)
class Meta:
model = Application
fields = {'created': '__all__'}
in your url :
http://localhost:8020/applications/?created__date=19-07-2017
Some of the answers below mention the use of lookup_expr='icontains'. Whilst this does work, it will yield incorrect results when the apps timezone is not UTC. This is because the date field returns the datetime stamp in UTC.
The result is that if an object has a date in UTC+2, of 2022-07-31 00:30, this will be returned as 2022-07-30 22:30, yielding incorrect results. It will be included in a filtered queryset of date 2022-07-30 and not 2022-07-31 as we expect.
Instead, we can the field name to return the date, where Django already does the conversion of the date using the specified timezone in the settings.py file. This can be done by using field_name='created__date' rather than lookup_expr='icontains' so that it is timezone aware.
created=django_filters.DateFilter(field_name='created__date')
I want to extract some particular columns from django query
models.py
class table
id = models.IntegerField(primaryKey= True)
date = models.DatetimeField()
address = models.CharField(max_length=50)
city = models.CharField(max_length=20)
cityid = models.IntegerField(20)
This is what I am currently using for my query
obj = table.objects.filter(date__range(start,end)).values('id','date','address','city','date').annotate(count= Count('cityid')).order_by('date','-count')
I am hoping to have a SQL query that is similar to this
select DATE(date), id,address,city, COUNT(cityid) as count from table where date between "start" and "end" group by DATE(date), address,id, city order by DATE(date) ASC,count DESC;
At least in Django 1.10.5, you can use something like this, without extra and RawSQL:
from django.db.models.functions import Cast
from django.db.models.fields import DateField
table.objects.annotate(date_only=Cast('date', DateField()))
And for filtering, you can use date lookup (https://docs.djangoproject.com/en/1.11/ref/models/querysets/#date):
table.objects.filter(date__date__range=(start, end))
For the below case.
select DATE(date), id,address,city, COUNT(cityid) as count from table where date between "start" and "end" group by DATE(date), address,id, city order by DATE(date) ASC,count DESC;
You can use extra where you can implement DB functions.
Table.objects.filter(date__range(start,end)).extra(select={'date':'DATE(date)','count':'COUNT(cityid)'}).values('date','id','address_city').order_by('date')
Hope it will help you.
Thanks.
If I have a Django Employee model with a start_date and end_date date field, how can I use get in the ORM to date effectively select the correct record if different versions of the record exist over time based on these date fields?
So I could have the following records:
start_date, end_date, emp
01/01/2013, 31/01/2013, Emp1
01/02/2013, 28/02/2013, Employee1
01/03/2013, 31/12/4000. EmpOne
And if today's date is 10/02/2013 then I would want Employee1.
Something similar to:
from django.utils import timezone
current_year = timezone.now().year
Employee.objects.get(end_date__year=current_year)
or
res = Employee.objects.filter(end_date__gt=datetime.now()).order_by('-start_date')
Or is there a more efficient way of doing the same?
Your second example looks fine. I corrected the filter parameters to match your start_date constraints. Also, i added a LIMIT 1 ([:1]) for better performance:
now = datetime.now()
employees = Employee.objects.filter(start_date__lt=now, end_date__gt=now).order_by('-start_date')
employee = employees[:1][0] if employees else None
In django, I want to get the age (in days) of an instance of a class. I tried doing that by subtracting its creation date field from today, but it does not seem to work properly. date.today() works fine, but DateField is giving me trouble. I looked at its source code and the django docs online for my version but I'm not sure how to manipulate it to perform the subtraction.
import datetime.date
from django.db import models
class MyItem(models.Model):
item_name = models.CharField(max_length = 30)
creation_date = models.DateField()
def age(self):
return date.today() - creation_date
my_first_item = MyItem(item_name = 'First', creation_date = '2005-11-01')
print my_first_item.age.days
Any input would be greatly appreciated!
Your problem is that you are trying to use a field instance outside of a model to represent a value.
models.DateField is a class which represents a database field with a type of "date". I suspect that you are looking to do one of the following:
Just do straight date math
Work with a value returned by a model
In the case of 1, you don't want to use Django's models at all. All you need and want is python's date and time handling classes. For your specific example all you need to use is a pair of date objects and you will end up with a timedelta object.
To do what you were trying to do in your example with the python standard classes, see the example below:
from datetime import date
birthday = date(year=2005, month=11, day=1)
today = date.today()
age = today - birthday
print age.days()
Here we instantiate a date with the birthdate values, we get a date with today's values, subtract them to get a timedelta, and finally print the number of days between the two dates.
In the case of 2, let's look at an example model:
class Person(models.Model):
name = models.CharField(max_length=100)
birthday = models.DateField()
Here we have a model where we've used models.CharField and models.DateField to describe a table in the database which contains a "varchar" column and a "date" column. When we fetch instances of this model using the ORM, Django handles converting whatever value the database returns to a native datatype. Now let's look at some code that figures out the age of an instance of a person:
from datetime import date
from myapp.models import Person
person = Person.objects.get(id=1)
age = date.today() - person.birthday
print age.days
Here you can see that we fetch an instance of the person model from the database and then we subtract their birthday from today. We're able to do this here, because when we access "person.birthday" Django is transforming whatever value the database returned into a python date object. This is the same type as the date object returned by "date.today()" so the "-" operator makes sense. The result of the subtraction operation is a timedelta object.