Find Out A Datetime is Between Two Datetimes in Django [duplicate] - python

This question already has answers here:
How do I filter query objects by date range in Django?
(8 answers)
Closed 6 years ago.
I'm making a blog-like platform which includes an event page. I have a model as below:
class Event(models.Model):
dtime_start = models.DateTimeField(null=False, blank=False)
dtime_end = models.DateTimeField(null=False, blank=False)
Assuming I have a view called event_main which projects all events. However, I want to project currently active events at the top of page, highlighted. So what I need is:
to get exact request datetime of client
to filter Event instances having the request datetime between dtime_start and dtime_end
I thought of solutions including for loops and put the results in the list, however I don't really want to put model instances to a list, since there are QuerySets. Is there a built-in way to do this in Django?
###############
# Environment #
###############
python 3.2.5
pypy 2.4.0
django 1.8.7

To get the request datetime of the client, you may :
Rely on the "Date" header (request.META.get('HTTP_DATE')),
Rely on the current date of the server and the client timezone
Fallback to the current date of the server
Then you can filter with common lookups as you would to for an integer:
Event.objects.filter(dtime_start__lte=request_datetime,
dtime_end__gte=request_datetime)
Note: Unless you have some specific reasons to rely on the client's date, you should probably avoid it and simply use datetime.now() or timezone.now() (both would work the same, as Django handles timezone conversion when dealing with the database). If you rely on the client's date, beware that they could temper with the Date header to access past or future events.

The dtime_start <= input AND dtime_end >= output:
Event.objects.filter(dtime_start__lte=datetime.date(y, m, d), dtime_start__gte=datetime.date(y, m, d))
For more information, refer to the documentation.

Related

Why python datetime replace timezone is returning different timezone?

I am working on Python/Django project. I am trying to let user select date and time using jQuery plugin datetimepicker add-on. So when I select now option and post data django is saving the time in UTC offset. This is what is saved in database, 2017-03-30 13:38:00+00:00. I need to convert this time from user's timezone and save it in system as utc. Because later I will have script running which will look for data in database which is less than the utc time.
Actually the script is to let user post information on website and let them chose the publish date and time. So for example, If use posted an article which will be published on April 2nd 1pm Chicago time, I don't want other users to read the article before this time. So people around the world can read article as soon as it is April 2nd and 1PM in Chicago. So how can I make this functionality work?
My solution was to get the time and remove it's timezone information using replace(tzinfo=pytz.timezone('America/Chicago')) and when I print the time, I am getting 2017-03-30 13:38:00-05:51. The actual offset right now is -05:00. Can anyone help me to and tell me what I am doing wrong?
What I am doing for form is that I have publish_date object in my model and I am using django forms to create form. I have added class as an attribute in it and using jquery plugin,
$('.datepicker').datetimepicker({
timeFormat: 'HH:mm',
stepHour: 1,
stepMinute: 1,
});
So when User submits the form, on post method this my code,
form = PublishForm(request.POST)
if form.is_valid():
f = form.save(commit=False)
f.created_by_user_id = request.user.id
f.save()
and than to get the date all I am doing is f.publish_date and the other options I have used lice replace and localize are pretty standard.
Thanks
As noted in the comments, you appear to have two problems. First is that the datetimepicker is saving a date and time with a UTC timezone offset, when it should be applying a different timezone or leaving off the timezone offset entirely. Second is that pytz is using the wrong offset.
I don't know how to fix the first problem, but I can help you with the second. You need to use pytz's localize function. This only works when the datetime doesn't have a timezone attached, but since you know the timezone is incorrect anyway you can delete it first.
tz = pytz.timezone('America/Chicago')
dt = tz.localize(dt.replace(tzinfo=None))
The naming of the datetime replace(tzinfo = ...) function is unfortunate. In fact, its behaviour is random. Do not use this!
Mark's answer is the way to go. Use localize.

Django - in the model, created_at is a UNIX timestamp

I am new to Django. I would have better grasp of this in Rails but am not familiar enough with all the libraries and converstions in Python / Django.
I have a model:
class Status(models.Model):
created = models.DatetimeField(auto_now_add=True)
This results in the format:
"created": "2017-01-06T22:21:51.531723Z"
I was hoping to see if before saving to the DB that it stores as a UNIX value?
This looked promising https://stackoverflow.com/a/34843855/3007294 but can't get it working. Every time I try to create a Status object, I get this error:
Datetime has wrong format. Use one of these formats instead: YYYY-MM-DDThh:mm[:ss[.uuuuuu]][+HH:MM|-HH:MM|Z].
My intentions are to not have to enter this every time a Status object is created.
Thanks -
My intentions are to not have to enter this every time a Status object is created.
This is already taken care of with the auto_now_add=True option. When you create a Status object, the created field will be populated with the current datetime.
I was hoping to see if before saving to the DB that it stores as a UNIX value?
You can convert the datetime value from Status.created to a Unix timestamp anytime required. Storing it in the default database datetime format (which is what DatetimeField does) is generally preferred to storing it as a timestamp, which is just an integer.
However, the library used in the example you provided, django-unixdatetimefield, states that "UnixDateTimeField is based on the implementation of the standard Django DateTimeField, making it 100% compatible with all features and options it supports." So, you should be able to provide the auto_now_add=True option to that field.

Redis python-rom object expiration.

I am working with flask and redis. I've decided to try the rom redis orm (http://pythonhosted.org/rom/) to manage some mildly complex data structures. I have a list of objects, lets say:
urls = ['www.google.com', 'www.example.com', 'www.python.org']
I also have the rom model:
class Stored_url(rom.Model):
url = rom.String(required=True, unique=True, suffix=True)
salt = rom.String()
hash = rom.String()
created_at = rom.Float(default=time.time)
This appears to be working on my dev setup. In my situation, i would like to start from scratch every day with some of the data and would like to set an expiration time for some objecta. I've looked through the documentation at http://pythonhosted.org/rom/rom.html# , but have not found a reference to expiration except in request caching. Is there a way to allow rom objects to expire?
Rom does not offer a built-in method automatic to automatically expire data. This is on purpose. I have explained the reasons why on 3 previous occasions:
https://github.com/josiahcarlson/rom/issues/40
https://github.com/josiahcarlson/rom/pull/47
https://github.com/josiahcarlson/rom/issues/62
TL;DR; Redis does not offer the internal mechanisms necessary to make this automatic (triggers). I provide 2 workarounds in the pull request linked above.
From rom documentation, it's better to create a new expire_at float column with index=True, the column can store when the entity is to expire. Then to expire the data, you can use: Model.query.filter(expire_at=(0, time.time())).limit(10) to (for example) get up to the 10 oldest entites that need to be expired.
https://josiahcarlson.github.io/rom/rom.html#expiring-models-ttls

Which datatype in Django model to be used to save HTML5 type "month" in database

I have a HTML form with field which takes input as month
<input type='month' name="last_appraisal" id='txtLastAppraisal' value='2013-12' />
In my Django model this field is defined as
last_appraisal = models.DateField(blank=True, null=True)
When I try to save this value (received from request.POST) in database then I get format error.
last_appraisal = request.POST.get('last_appraisal','')
if last_appraisal != '':
mymodel.last_appraisal = last_appraisal
mymodel.save()
ERROR: raise exceptions.ValidationError(msg)
ValidationError: [u"'2013-01' value has an invalid date format. It must be in YYYY-MM-DD format."]
I know I can achieve this by adding a default day(maybe 01) to this input month and then save into the database. And while fetching back this value I can re-format it like "YYYY-MM" and send it back to template.
But I want to know if there's any better way to achieve this. I am using Django 1.5.1 and Python 2.7.
EDITED:
After reading all the responses it is clear that Django doesn't have built-in support for this format. Now I have few choices
My way to add day into date field.
As suggested by #Odif to take database field as 'CharField'
As suggested by #Ghopper21 to create a Custom Django field
My preference will be the choice1 because using this
I don't have to write some extra complex code compare to choice3.
I get the flexibility to use this field in table searches like 'find all candidates who got their appraisal in Jun 2013' which I loose if I go for chioce2.
Don't know whether my choice is good or bad but considering the size of project and time to complete it I think this will be the best choice. Please comment if you think this is absolutely rubbish or if you are in favor of this approach.
There are two issues here: Django doesn't have a built-in way to deal with month/year-only dates, and nor does Python.
If you are ok with a convenient way to translate the month/year-only dates into full dates with the day set to 1, but just don't want to have to do this manually in your view code every time, you can encapsulate that logic in a custom Django widget, which is a component for translating between the Django field representation (in this case a DateField) and the HTML input field.
If you need to have the underlying Python representation of the date to be month/year-only in a first class way, I'd suggest looking into the excellent Python library dateutil's relativedelta class -- which allows you to specify things like relativedelta(year=2013, month=12). If you want to use that, you'd then have to create a custom Django model field that translates between relativedelta instances and database storage via serialization. You'd then still need a custom widget for the HTML side of things.
Use models.CharField. DateField and DateTimeField expect date and datetime object respectively. Since '2013-01' cannot be coerced into either, then use CharField. Or use integerfield and just post month.

Django model TimeField views.py cannot select hour or minute

When using a TimeField in a Django model I wish to be able to perform a query in a view, using the hour and minute elements of the TimeField separately.
However, when I do so, if I run the view I receive an error message that the __hour (or __minute) does not exist (see code below):
scheduleItems = DEVICESCHEDULE.objects.filter(time__hour = nowHour)
If I change the model to use a DateTimeField rather than a TimeField, I am able to use the __hour and __minute options.
I would prefer to keep the field type as a TimeField, as I only need a time to be input and inputting a date (even if it is ignored) is confusing to the user.
Thanks in advance!
Seem like the date/time related lookups only works with dates and datetimes, not the time fields, although seems like it would be a nice feature to have as well.
Have you thought about raising a ticket maybe?
Maybe you can consider this as a replacement:
DEVICESCHEDULE.objects.extra(where=['SUBSTR(time, 1, 2)=%0.2d'], params=[nowHour])
DEVICESCHEDULE.objects.extra(where=['SUBSTR(time, 4, 2)=%0.2d'], params=[nowMinute])

Categories