timezone support in django - django

I'm trying to get the various US timezones supported in Django. I'm able to get the America/New_York, etc. But my question is for places like Hawaii? I'm not able to find the proper timezone setting for it? Is there a place for all the available settings that we can use in Django? I want to build an application and give the user the ability to choose the timezone they are in.. Thanks for the help!

See "What you need to know about date/time" (nice video from PyCon 2012).
>>> import pytz
>>> pytz.all_timezones
['Africa/Abidjan',
'Africa/Accra',
'Africa/Addis_Ababa'
...
'US/Pacific-New',
'US/Samoa',
'UTC',
'Universal',
'W-SU',
'WET',
'Zulu']
Data available:
all_timezones = ['Africa/Abidjan', 'Africa/Accra', ...]
all_timezones_set = set(['Africa/Abidjan', 'Africa/Accra', ...]
common_timezones = ['Africa/Abidjan', 'Africa/Accra', ...]
common_timezones_set = set(['Africa/Abidjan', 'Africa/Accra', ...])
country_names = {u'BD': u'Bangladesh', u'BE': u'Belgium', ...}
country_timezones = {u'BD': [u'Asia/Dhaka'], u'BE': [u'Europe/Brussels'] ...}

Related

Django: Trying to add 'SHORT_TIME_FORMAT' somehow changes time zone to Chicargo

I required some extra date/time formats in addition to ones Django ships with, sI created these new formats:
SHORT_TIME_FORMAT
FILE_DATETIME_FORMAT
ISO8601_DATETIME_FORMAT.
So that I could use them in templates like this:
{{ value|date:"SHORT_DATE_FORMAT" }}
And In code like this:
from django.utils import formats
formats.date_format(value, `SHORT_TIME_FORMAT`)
I created the following code in utils/time/formats.py:
from collections import ChainMap
from django.utils import formats
DJANGO_DATETIME_FORMATS = {
'DATETIME_FORMAT': 'd M Y, H:i',
'DATE_FORMAT': 'j M Y',
'TIME_FORMAT': 'H:i:s',
'SHORT_DATETIME_FORMAT': 'Y-m-d H:i:s',
'SHORT_DATE_FORMAT': 'Y-m-d',
'MONTH_DAY_FORMAT': 'd M',
'YEAR_MONTH_FORMAT': 'Y M',
}
EXTRA_DATETIME_FORMATS = {
'SHORT_TIME_FORMAT': 'H:i',
'FILE_DATETIME_FORMAT': 'Y-m-d H.i.s',
'ISO8601_DATETIME_FORMAT': 'c', # Compatible with Javascript passing
}
def set_formats(globals_dict):
"""Returns a set of datetime formats for use across the whole project
Contains a union of the default formats along with the additional ones.
To add a new format, one has to perform the following two actions:
1. Add the name of the format to formats.FORMAT_SETTINGS
2. Add a variable with the same name as the variable to the settings.py
file with the value assigned to the required format.
globals_dict is the globals from the settings.py file
"""
formats.FORMAT_SETTINGS = frozenset(formats.FORMAT_SETTINGS | EXTRA_DATETIME_FORMATS.keys())
all_formats = ChainMap(DJANGO_DATETIME_FORMATS, EXTRA_DATETIME_FORMATS)
for setting, value in all_formats.items():
globals_dict[setting] = value
However when I add it to my settings.py file as so:
# settings.py
from utils.time.formats import set_formats
set_formats(globals())
My timezone changes to Chicargo, even though in settings.py I have:
TIME_ZONE = 'Africa/Johannesburg'
After research I found out that Django's default timezone is Chicargo, which is 7 Hrs behind me (I am UTC+02).
I can test it like this:
$ python manage.py shell
> from django.utils import timezone
> from django.conf import settings
> print(f"The settings.py TIME_ZONE value is: {settings.TIME_ZONE=}")
The settings.py TIME_ZONE value is: settings.TIME_ZONE='Africa/Johannesburg'
> print("Using Django local time, now is:")
Using Django local time, now is:
> print(timezone.localtime())
2022-07-27 20:54:35.293958+02:00
If I don't use set_formats, the datetime is correctly in my local time, if I add my set_formats function, then datetime is 7 Hrs off, and in the admin interface and other date/times on my website are all 7 hours off, even though settings.TIME_ZONE reports Africa/Johannesburg.
this code used to work, but at some point recently stopped working. I did change from pytz to zoneinfo, so that might be the reason, but I was a little bit sure it worked after the change.
Why is the timezone changing? How can I add a date/time format so it can be used in templates and in code with the django.utils.formats.date_format function?

Getting the list of timezones supported by PostgreSQL in Django using RawSQL

I am trying to get the list of all the timezones supported by PSQL database in my Django project, so I can validate timestamps with timezones before sending them to the the database. I asked another question and got an answer regarding the PSQL query here:
How to get the list of timezones supported by PostgreSQL?
Using that, I am trying to do the following:
from django.db.models.expressions import RawSQL
RawSQL("SELECT name, abbrev, utc_offset, is_dst FROM pg_timezone_names;", [])
However, it does not seem to work. I saw the docs for RawSQL, and it usually has a model attached to it, which I can't really have. How to do solve this issue? Thanks.
Following should work for you
from django.db import connection
with connection.cursor() as cursor:
cursor.execute("SELECT name, abbrev, utc_offset, is_dst FROM pg_timezone_names")
zones = cursor.fetchall()

Python library to access a CalDAV server

I run ownCloud on my webspace for a shared calendar. Now I'm looking for a suitable python library to get read only access to the calendar. I want to put some information of the calendar on an intranet website.
I have tried http://trac.calendarserver.org/wiki/CalDAVClientLibrary but it always returns a NotImplementedError with the query command, so my guess is that the query command doesn't work well with the given library.
What library could I use instead?
I recommend the library, caldav.
Read-only is working really well with this library and looks straight-forward to me. It will do the whole job of getting calendars and reading events, returning them in the iCalendar format. More information about the caldav library can also be obtained in the documentation.
import caldav
client = caldav.DAVClient(<caldav-url>, username=<username>,
password=<password>)
principal = client.principal()
for calendar in principal.calendars():
for event in calendar.events():
ical_text = event.data
From this on you can use the icalendar library to read specific fields such as the type (e. g. event, todo, alarm), name, times, etc. - a good starting point may be this question.
I wrote this code few months ago to fetch data from CalDAV to present them on my website.
I have changed the data into JSON format, but you can do whatever you want with the data.
I have added some print for you to see the output which you can remove them in production.
from datetime import datetime
import json
from pytz import UTC # timezone
import caldav
from icalendar import Calendar, Event
# CalDAV info
url = "YOUR CALDAV URL"
userN = "YOUR CALDAV USERNAME"
passW = "YOUR CALDAV PASSWORD"
client = caldav.DAVClient(url=url, username=userN, password=passW)
principal = client.principal()
calendars = principal.calendars()
if len(calendars) > 0:
calendar = calendars[0]
print ("Using calendar", calendar)
results = calendar.events()
eventSummary = []
eventDescription = []
eventDateStart = []
eventdateEnd = []
eventTimeStart = []
eventTimeEnd = []
for eventraw in results:
event = Calendar.from_ical(eventraw._data)
for component in event.walk():
if component.name == "VEVENT":
print (component.get('summary'))
eventSummary.append(component.get('summary'))
print (component.get('description'))
eventDescription.append(component.get('description'))
startDate = component.get('dtstart')
print (startDate.dt.strftime('%m/%d/%Y %H:%M'))
eventDateStart.append(startDate.dt.strftime('%m/%d/%Y'))
eventTimeStart.append(startDate.dt.strftime('%H:%M'))
endDate = component.get('dtend')
print (endDate.dt.strftime('%m/%d/%Y %H:%M'))
eventdateEnd.append(endDate.dt.strftime('%m/%d/%Y'))
eventTimeEnd.append(endDate.dt.strftime('%H:%M'))
dateStamp = component.get('dtstamp')
print (dateStamp.dt.strftime('%m/%d/%Y %H:%M'))
print ('')
# Modify or change these values based on your CalDAV
# Converting to JSON
data = [{ 'Events Summary':eventSummary[0], 'Event Description':eventDescription[0],'Event Start date':eventDateStart[0], 'Event End date':eventdateEnd[0], 'At:':eventTimeStart[0], 'Until':eventTimeEnd[0]}]
data_string = json.dumps(data)
print ('JSON:', data_string)
pyOwnCloud could be the right thing for you. I haven't tried it, but it should provide a CMDline/API for reading the calendars.
You probably want to provide more details about how you are actually making use of the API but in case the query command is indeed not implemented, there is a list of other Python libraries at the CalConnect website (archvied version, original link is dead now).

how to write a query to get find value in a json field in django

I have a json field in my database which is like
jsonfield = {'username':'chingo','reputation':'5'}
how can i write a query so that i can find if a user name exists. something like
username = 'chingo'
query = User.objects.get(jsonfield['username']=username)
I know the above query is a wrong but I wanted to know if there is a way to access it?
If you are using the django-jsonfield package, then this is simple. Say you have a model like this:
from jsonfield import JSONField
class User(models.Model):
jsonfield = JSONField()
Then to search for records with a specific username, you can just do this:
User.objects.get(jsonfield__contains={'username':username})
Since Django 1.9, you have been able to use PostgreSQL's native JSONField. This makes search JSON very simple. In your example, this query would work:
User.objects.get(jsonfield__username='chingo')
If you have an older version of Django, or you are using the Django JSONField library for compatibility with MySQL or something similar, you can still perform your query.
In the latter situation, jsonfield will be stored as a text field and mapped to a dict when brought into Django. In the database, your data will be stored like this
{"username":"chingo","reputation":"5"}
Therefore, you can simply search the text. Your query in this siutation would be:
User.objects.get(jsonfield__contains='"username":"chingo"')
2019: As #freethebees points out it's now as simple as:
User.objects.get(jsonfield__username='chingo')
But as the doc examples mention you can query deeply, and if the json is an array you can use an integer to index it:
https://docs.djangoproject.com/en/2.2/ref/contrib/postgres/fields/#querying-jsonfield
>>> Dog.objects.create(name='Rufus', data={
... 'breed': 'labrador',
... 'owner': {
... 'name': 'Bob',
... 'other_pets': [{
... 'name': 'Fishy',
... }],
... },
... })
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': None})
>>> Dog.objects.filter(data__breed='collie')
<QuerySet [<Dog: Meg>]>
>>> Dog.objects.filter(data__owner__name='Bob')
<QuerySet [<Dog: Rufus>]>
>>> Dog.objects.filter(data__owner__other_pets__0__name='Fishy')
<QuerySet [<Dog: Rufus>]>
Although this is for postgres, I believe it works the same in other DBs like MySQL
Postgres: https://docs.djangoproject.com/en/2.2/ref/contrib/postgres/fields/#querying-jsonfield
MySQL: https://django-mysql.readthedocs.io/en/latest/model_fields/json_field.html#querying-jsonfield
This usage is somewhat anti-pattern. Also, its implementation is not going to have regular performance, and perhaps is error-prone.
Normally don't use jsonfield when you need to look up through fields. Use the way the RDBMS provides or MongoDB(which internally operates on faster BSON), as Daniel pointed out.
Due to the deterministic of JSON format,
you could achieve it by using contains (regex has issue when dealing w/ multiple '\' and even slower), I don't think it's good to use username in this way, so use name instead:
def make_cond(name, value):
from django.utils import simplejson
cond = simplejson.dumps({name:value})[1:-1] # remove '{' and '}'
return ' ' + cond # avoid '\"'
User.objects.get(jsonfield__contains=make_cond(name, value))
It works as long as
the jsonfield using the same dump utility (the simplejson here)
name and value are not too special (I don't know any egde-case so far, maybe someone could point it out)
your jsonfield data is not corrupt (unlikely though)
Actually I'm working on a editable jsonfield and thinking about whether to support such operations. The negative proof is as said above, it feels like some black-magic, well.
If you use PostgreSQL you can use raw sql to solve problem.
username = 'chingo'
SQL_QUERY = "SELECT true FROM you_table WHERE jsonfield::json->>'username' = '%s'"
User.objects.extra(where=[SQL_EXCLUDE % username]).get()
where you_table is name of table in your database.
Any methods when you work with JSON like with plain text - looking like very bad way.
So, also I think that you need a better schema of database.
Here is the way I have found out that will solve your problem:
search_filter = '"username":{0}'.format(username)
query = User.objects.get(jsonfield__contains=search_filter)
Hope this helps.
You can't do that. Use normal database fields for structured data, not JSON blobs.
If you need to search on JSON data, consider using a noSQL database like MongoDB.

Getting users latest tweet with Django

I want to create a function which grabs every users latest tweet from a specific group. So, if a user is in the 'authors' group, I want to grab their latest tweet and then finally cache the result for the day so we only do the crazy leg work once.
def latest_tweets(self):
g = Group.objects.get(name='author')
users = []
for u in g.user_set.all():
acc = u.get_profile().twitter_account
users.append('http://twitter.com/statuses/user_timeline/'+acc+'.rss')
return users
Is where I am at so far, but I'm at a complete loose end as to how I parse the RSS to get there latest tweet. Can anyone help me out here? If there is a better way to do this, any suggestions are welcome! I'm sure someone will suggest using django-twitter or other such libraries, but I'd like to do this manually if possible.
Cheers
why redo the stone?, you can download/install/import python-twitter and do something like:
tweet = twitter.Api().GetUserTimeline( u.get_profile().twitter_account )[0]
http://code.google.com/p/python-twitter/
an example: http://www.omh.cc/blog/2008/aug/4/adding-your-twitter-status-django-site/
Rss can be parsed by any xml parser. I've used the built-in module htmllib before for a different task and found it easy to deal with. If all you're doing is rss parsing though, I'd recommend feedparser. I haven't used it before, but it seems pretty straight forward.
If you go with python-twitter it is pretty simple. This is from memory so forgive me if I make a mistake here.
from django.core.cache import cache
import twitter
TWITTER_USER = 'username'
TWITTER_TIMEOUT = 3600
def latest_tweet(request):
tweet = cache.get('tweet')
if tweet:
return {"tweet":tweet}
api = twitter.Api()
tweets = api.GetUserTimeline(TWITTER_USER)
tweet = tweets[0]
tweet.date = datetime.strptime(
tweet.created_at, "%a %b %d %H:%M:%S +0000 %Y"
)
cache.set( 'tweet', tweet, TWITTER_TIMEOUT )
return {"tweet": tweet}