Django, queryset, filter today - python

I'm trying to query the database and get the entries for today. So I got a model Events with a date time field. Just to clarify, if I remove the date filter, it does return entries from the database. If I add them it does not. I double-checked that there is an item for today.
views.py
def dashboard(request):
if request.user.is_authenticated():
now = datetime.datetime.now()
events_today = Event.objects.filter(date__year=now.year, date__month=now.month, date__day=now.day)
return render_to_response("dashboard.html", {'today': events_today,}, RequestContext(request))
Update
It does work if I change the USE_TZ to False in settings.py. But it doesn't if it's True.
Update 2
I even uploaded the project to my VPS just in case it had something to do with my computer but still the same.

Instead of datetime.datetime.now() use timezone.now():
from django.utils import timezone
timezone.now()

I think you can try this query:
events_today = Event.objects.filter(date=datetime.datetime.today())

Related

Django DateTimeField says 'You are 5.5 hours ahead of server time.'

In one of my model I am storing time_stamp = models.DateTimeField(default=timezone.now)
But when I save the model it says You are 5.5 hours ahead of server time.
for example local time in my machine is 13:02 but after saving what gets stored in db is 7:16
I got one related here but it does not an have a satisfying answer...
models.py
class Comment(models.Model):
time_stamp = models.DateTimeField(default=timezone.now)
def save(self, *args, **kwargs):
''' On save, update timestamps '''
if not self.id:
self.time_stamp = timezone.now()
return super(Comment, self).save(*args, **kwargs)
As you are 5.5 hrs ahead of server time, I am assuming, you are in India.
So put appriopriate timezone in settings.py
TIME_ZONE = 'Asia/Kolkata'
If somewhere else, set accordingly
Make sure you make the following change in the settings.py file in your Django project.
If it is saying that you are 5.5 hours ahead of server time. It means that you are in India then set
TIME_ZONE = 'Asia/Kolkata'
in your setting.py file.
Or check your time zone at
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
You need to change the time zone settings on your PC and refresh. That is the only way out. I just fixed my own through that.

Working with several time zone in Django

The application I am working on has as target users USA. And (as you may know) in USA there's more than one time zone. So I have some doubts:
so how could I get the current time in server side based on the
current user?
And how could I store DateTime data to show the correct time for
every user?
How can I compare times (example: user.event.created > datetime.now())? What timezone will .now() use?
What TIME_ZONE should I set in settings.py file.
This is for an API, to grab user's timezone via JS is not an option. I get the current user via TokenAuthentication.
Use UTC for settings.py and grab their timezone offset from Javascript:
var utcOffset = -((new Date()).getTimezoneOffset()) / 60;
e.g. for Los Angeles right now utcOffset == -7
Unfortunately this doesn't account for Daylight Savings Time changes later (offset changes to -8), so you may have to figure that out at the time of retrieval in order to get Pacific/Los_Angeles. Otherwise you could always just ask the user in a signup form if it's important for your business.
EDIT: Since you're using an API, you could also try using the IPInfoDB API to geolocate based on client IP address. It's not always completely accurate, but almost always enough to get the correct timezone.
Don't use datetime.now(), use the now() function in the timezone module instead.
from django.utils import timezone
now = timezone.now()
Django will figure out which timezone you are in and compare them accordingly.
user.event.created > timezone.now()
https://docs.djangoproject.com/en/1.8/topics/i18n/timezones/
The solution is to always store unix timestamps in the database. You can generate with time.time() . That means your model should have a Floatfield (or even a BigIntegerField depending on the accuracy needed).
Your template should display the numeric value as it is. Then you need a tiny bit of javascript to convert that unix timestamp to a date time.
new Date(unix_timestamp);
The users of your webapp may be in different time zones, so the conversion to an appropriate time zone is necessary. You can create a middleware and use activate function to set the appropriate time zone. You can get the client-side timezone by doing an ajax api call to Free IP Geolocation API in your landing page and the timezone value can be saved in a cookie variable which can be later accessed in the middleware.
landingpage.html
<script>
$.ajax({
url: 'https://freegeoip.app/json/',
dataType: 'json',
success: function (data) {
document.cookie = 'timezone=' + data['time_zone'] + '; path=/';
}
});
</script>
middleware.py
import pytz
import requests
from django.utils import timezone
class TimezoneMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
tzname = request.COOKIES.get('timezone')
if tzname:
timezone.activate(pytz.timezone(tzname))
else:
timezone.deactivate()
return self.get_response(request)
settings.py
MIDDLEWARE = [ ........
'projectname.middleware.TimezoneMiddleware',
]

Django DateTimeField from form to UTC

I have a small Django app with a form, wich saves some data to the DB.
Here's the form:
class SomeForm(forms.Form):
time = forms.DateTimeField()
...
And the view, where I save it:
class AccountAddIncome(View):
def save(self, form):
model = Model(
time=form.cleaned_data['time']
)
model.save()
def post(self, request, *args, **kwargs):
form = SomeForm(request.POST)
if form.is_valid():
self.save(form)
return redirect(self.success_url)
else:
...
My problem is, that the Django admin says: "Note: You are 1 hour ahead of server time."
The date command on my Ubuntu (the server) says exactly the same date as my computer has.
But, when I save this object in the DB, and make the following query:
Model.objects.filter(time__lt=timezone.now())
django do not list the previously saved model for an hour. If I go to the admin, and set the time back one hour, django'll show that object.
So, my question is, what's the best practice, to manage datetime objects in django?
I want to save everything in UTC, but I cannot convert that datetime from the form to UTC.
go to settings.py of your Django project
comment timezone settings and use TIME_ZONE = timezone.now()
from django.utils import timezone
TIME_ZONE = timezone.now()
# TIME_ZONE = 'UTC'
# USE_I18N = True
# USE_L10N = True
# USE_TZ = True
Than you will never see this - Note: You are 1 hour ahead of server time.

Django querying on range of days with timezone.now and __range broken?

I am running Django 1.4.3 and Python 2.7, with a PostgreSQL database (9.2.2). I have a model with a "last_view" field that is a timestamp of when a record is last viewed by a user. On my front page I want to display the ten most viewed items within the last week, so in my ListView I tried using this for my queryset:
startdate = timezone.now() - datetime.timedelta(days=7)
enddate = timezone.now()
urlpatterns = patterns('',
url(r'^$',
ListView.as_view(
queryset=Tag.objects.filter(last_view__range=([startdate, enddate])).order_by('-views')[:10],
context_object_name='most_viewed_list',
template_name='tags/index.html'),
name='index'),
This works when I first load the page. If I click any of the records and "view" them, the last_view attribute is updated in the database--but if I then reload the page, this item disappears from the "Recently Viewed" list (formed by the queryset described above).
I thought the problem was related to this post, where it seems like the "enddate" of timezone.now() is limited by when I start my server process. So when I click on a link after the server is running, the "current time" is in the future compared to "now()" and outside of the range (that is why the record I click disappears on a page reload). However, if I change things to just now as in the post mentioned above, I get an error on page load:
startdate = timezone.now - datetime.timedelta(days=7)
enddate = timezone.now
unsupported operand type(s) for -: 'function' and 'datetime.timedelta'
So I cannot create my startdate variable. I can get this to work by changing my queryset from _range to _gte, but it seems like that will break over time if now() is really timestamped to when the server process starts instead of "current time."
queryset=Tag.objects.filter(last_view__gte=(timezone.now() - datetime.timedelta(days=7)).order_by('-views')[:10]
The Django Tutorial on testing does show the use of now in making queries over dates, however they do not show how to subtract days from now or use it with timedelta or a date range...
Can someone please explain how to take a time difference from the actual, current time, i.e. using now instead of now()? I would also like to better understand the limitations of using now() versus now. I cannot find great documentation on this, since all examples I can find with timedelta() refer to timezone.now() or datetime.now(), which works (just not the way I want it to).
Thanks!
Subclass ListView and override the get_queryset method. By calculating the startdate and enddate inside the get_queryset method, timezone.now() will be the time when the request was made, not when the urls.py was initially loaded.
class TagListView(ListView):
def get_queryset(self):
startdate = timezone.now() - datetime.timedelta(days=7)
enddate = timezone.now()
return Tag.objects.filter(last_view__range=[startdate, enddate]).order_by('-views')[:10]
context_object_name='most_viewed_list'
template_name='tags/index.html'
urlpatterns = patterns('',
url(r'^$', TagListView.as_view(), name='index'),
)

templatetags don't refresh

I have two templatetags in my app which contain forms which show entries in db. When I alter data or add new entry to db, the forms show the old data. While in admin panel everything is correct (updated). When I restart the server (I mean manage.py runserver) forms show updated db entries. How to make the forms show updated data?
regards
chriss
EDIT:
file: templatetags/oceny_tags.py:
from django import template
from oceny.formularze import StudentFormularz, PrzeniesStudentaFormularz
def dodajStudenta(req):
formularz = StudentFormularz(req)
return {'formularz': formularz}
def przeniesStudenta(req):
formularz = PrzeniesStudentaFormularz(req)
return {'formularz': formularz}
register = template.Library()
register.inclusion_tag('oceny/formularz_studenta.html', takes_context = False)(dodajStudenta)
register.inclusion_tag('oceny/formularz_przenies_studenta.html', takes_context = False)(przeniesStudenta)
file: views.py view responsible for handling forms:
def zarzadzajStudentami(request):
formularze = ['dodaj_studenta', 'przenies_studenta']
req = {}
for e in formularze:
req[e] = None
if request.POST:
req[request.POST['formularz']] = request.POST
if request.POST['formularz'] == 'dodaj_studenta':
formularz = StudentFormularz(request.POST)
if formularz.is_valid():
formularz.save()
return HttpResponseRedirect(reverse('zarzadzaj_studentami'))
elif request.POST['formularz'] == 'przenies_studenta':
formularz = PrzeniesStudentaFormularz(request.POST)
if formularz.is_valid():
student = Student.objects.get(id = request.POST['student'])
grupa = Grupa.objects.get(id = request.POST['grupa'])
student.grupa = grupa
student.save()
return HttpResponseRedirect(reverse('zarzadzaj_studentami'))
return render_to_response('oceny/zarzadzaj_studentami.html', {'req': req}, context_instance = RequestContext(request))
I realize that the code may be lame in some cases. I would appreciate any other hints how to write things better.
I have too low rep to comment, but takes_context defaults to False, making your assignment redundant. Also, but now I am guessing, but it might be related to your problem.
Look for "CACHE_BACKEND= ????" in your settings.py file. The value will change as a function of which caching mechanism you are using. Comment this out and restart the server. If your values are now showing correctly, then it was a caching problem.
Are you using some kind of cache system? It could be that.

Categories