I have a model
class Booked(models.Model):
start_date_time = models.DateTimeField()
end_date_time = models.DateTimeField()
resource = models.ForeignKey(Resouce)
How do I check if a particular datetime range doesn't fall between the start or end datetimes of any of the booked objects?
I want to check if I can book a resource with say book_start_date and book_end_date without it being already booked during that range
Use __lte and __gte with exists() to check if there is something in the date range:
Booked.objects.exists(start_date_time__lte=book_end_date,
end_date_time__gte=book_start_date)
See also: Determine Whether Two Date Ranges Overlap.
Related
I am trying to filter date in Django according to current date, But it's displaying mr 0 results, Please let me know Where I am mistaking.
Hers is my models.py file...
class Customer(models.Model):
name = models.CharField(null=True, blannk=True)
customer_date = models.DateTimeField(null=True, blannk=True)
here is my views.py file, where i am trying to get date according to today date...
from datetime import datetime, timedelta, time, date
def getdate(request):
today=datetime.today()
customer_data = Customer.objects.filter(customer_date=today).count()
print(customer_data, "Count Values")
I see some issue in your date filter. When you do:
datetime.datetime.today()
#2020-11-04 10:57:22.214606
this give complete timestamp.
However you want to do date match only.so, try something like code.
today = datetime.today().date()
#today=datetime.today()
customer_data = Customer.objects.filter(customer_date__date=today).count()
hope this may help your query.
I saw you mistyped blank as blannk
I'm trying to get the number of months since a model is created.
My Model looks like this:
class Plan(models.Model):
title = models.CharField(max_length=50)
date_created = models.DateTimeField(default=timezone.now)
plan_type = models.IntegerField()
owner = models.ForeignKey(User, on_delete=models.CASCADE)
Now i want to make a method that returns the number of months since the date_created.
Tanks for any help :D
Comparing dates creates a datetime.timedelta object that you can use to get the difference between dates.
from datetime import timedelta
from django.utils.timezone import now
delta: timedelta = now() - plan.date_created
delta.days # Number of days between dates.
You can then use that value to convert it to months or years.
The other alternative would be a bit more complicated, but since DateTimeField returns a datetime.datetime object, you can also access the month number of the original date and compare it against todays date.
e.g.
from django.utils.timezone import now
month_diff = now().month - plan.date_created.month
The problem with the second alternative is that you then have to take into account if they are the same year or not, and if they are not you then have to take that into account when you get the month difference.
You can write a property in your model like
from django.utils import timezone
class Plan(models.Model):
title = models.CharField(max_length=50)
...
#property
def get_month(self):
return self.date_created.month - timezone.now().month
Then you can get the value like this
>>> Plan.objects.first().get_month
4
I have my django app and I want to pass from url to view years in format, for example: 2017-18.
Below I got an error that my date have to be in date format - YYYY-MM-DD.
Here is my url:
url(r'^(?P<branch_slug>/production/(?P<year1>[0-9]{4})-(?P<year2>[0-9]{2})$', Events.as_view()),
Here is my view:
def get_queryset(self):
season = Events.objects.get(start=self.kwargs['year1'], end=self.kwargs['year2'])
filter_['start__gte'] = season.start
filter_['start__lte'] = season.end
return self.model.objects.filter(**filter_)
The start and end attributes of your Event object are probably datetime.date instances (if you are using a DateField). So you need to convert the year1 and year2 variables from your url to a date before using them in your view.
some_date = datetime.date(YYYY, 1, 1)
Your original question, and others' answers here, match a season that begins on 1 January of year1 and ends on 31 December of year2. I suspect that this is not what you want, and that instead you want a season which starts sometime in year1 and ends some time in year2, and then you want to look up events between those dates.
Django has a special lookup for matching only the year part of a date, using __year=. See https://docs.djangoproject.com/en/1.10/ref/models/querysets/#year for more on this. You don't need to convert the input values to dates to use this; it works with integers.
def get_queryset(self):
# Get a season starting any time in year1 and ending in year2
season = Events.objects.get(
start__year=int(self.kwargs['year1']),
end__year=int(self.kwargs['year2']),
)
As with others have commented you should change the URL regex to match 4-digit years to avoid ambiguity.
url(r'^(?P<branch_slug>/production/(?P<year1>[0-9]{4})-(?P<year2>[0-9]{4})$', Events.as_view()),
As #dentemm pointed out, to do filtering on datetime fields, strings representing date must be converted to datetime objects. My suggestion is to use datetime field. Pass year string as you are already doing and then in the views convert date string to a datetime object to do filtering
import datetime
def get_queryset(self):
start=datetime.strptime('1-1-'+self.kwargs['year1'], '%m-%d-%Y')
end=datetime.strptime('12-31-'+self.kwargs['year2'], '%m-%d-%Y')
season = Events.objects.get(start=start, end=end)
filter_['start__gte'] = season.start
filter_['start__lte'] = season.end
return self.model.objects.filter(**filter_)
datetime.strptime('1-1-'+self.kwargs['year1'], '%m-%d-%Y') will create datetime object for start date with date as 1st of january for given start date string and datetime.strptime('12-31-'+self.kwargs['year2'], '%m-%d-%Y') will create datetime object for end date with date as 31st of december for given end date string. To make sure all objects created within end date is returned by query you may do something like
`end_date = datetime.strptime('31-12-'+self.kwargs['year1']+'T23:59:59.999999', '%m-%d-%YT%H:%M:%S.%f')`
As #Alasdair mnetioned in one of the comments change (?P<year2>[0-9]{2}) to (?P<year2>[0-9]{4}) to accept 4 digit year string from url
If you have a datetime/date field in your model, use the year lookup from Django:
https://docs.djangoproject.com/en/1.10/ref/models/querysets/#year
As it says:
Entry.objects.filter(pub_date__year=2005)
is equal in sql to:
SELECT ... WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31';
I have 2 fields for start date and end date.
How to get a rows that falls between the start and end dates.
That my model
class Shop(models.Model):
time_begin = models.TimeField(max_length=255,
verbose_name=u'Время начала работы')
time_end = models.TimeField(max_length=255,
verbose_name=u'Время окончания работы')
You can use django's filter with datetime.time objects:
import datetime
shops = Shop.objects.filter(time_begin__gte=datetime.time(10, 0, 0),
time_end__lte=datetime.time(22, 0, 0))
Same (__gte & __lte) can also work for DateTime or Date fields.
However, if you're using Django 2.2+ you can use the appropriate built-in filters __time, __hour, __minute or __second as per need.
You can use the __lt and __gt filters to target dates in between both.
Shop.objects.filter(time_begin__gte=<date>, time_end__lt=<date>)
If you're using DateField and want to include the end date, use lte, otherwise use lt.
I take a timestamp for my Institution class:
class Institution(models.Model):
timestamp_utc = models.DateTimeField()
If there is an entry in the DB that has the same year, month and date (not time), then I want to update the value of the entry. If not, then I want to create a new entry.
The conditional is as follows:
if Institution.objects.filter(timestamp_utc.strftime("%Y/%m/%d")=b['timestamp_utc'].strftime("%Y/%m/%d")).exists():
I am getting this error:
Exception Value: keyword can't be an expression
Is there a way to filter the DB object with a manipulated keyword?
You can just filter by the date range, i.e. time stamps that are great than or equal to the date, and less that the date + 1 day.
from datetime import relativedelta
date_start = b['timestamp_utc'].strftime("%Y-%m-%d")
date_end = (b['timestamp_utc'] + relativedelta(days=1)).strftime("%Y-%m-%d")
if Institution.objects.filter(
timestamp_utc__gte=date_start, timestamp_utc__lt=date_end
).exists():