1
0
mirror of https://github.com/django/django.git synced 2025-07-04 09:49:12 +00:00

i18n: merged to [992] from trunk

git-svn-id: http://code.djangoproject.com/svn/django/branches/i18n@993 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Georg Bauer 2005-10-23 10:18:03 +00:00
commit 174c8a0295
11 changed files with 502 additions and 30 deletions

View File

@ -299,7 +299,7 @@ def init():
cursor = db.db.cursor() cursor = db.db.cursor()
for sql in get_sql_create(core) + get_sql_create(auth) + get_sql_initial_data(core) + get_sql_initial_data(auth): for sql in get_sql_create(core) + get_sql_create(auth) + get_sql_initial_data(core) + get_sql_initial_data(auth):
cursor.execute(sql) cursor.execute(sql)
cursor.execute("INSERT INTO %s (domain, name) VALUES ('mysite.com', 'My Django site')" % core.Site._meta.db_table) cursor.execute("INSERT INTO %s (domain, name) VALUES ('example.com', 'Example site')" % core.Site._meta.db_table)
except Exception, e: except Exception, e:
sys.stderr.write("Error: The database couldn't be initialized.\n%s\n" % e) sys.stderr.write("Error: The database couldn't be initialized.\n%s\n" % e)
try: try:

View File

@ -1360,9 +1360,10 @@ def function_get_sql_clause(opts, **kwargs):
def function_get_in_bulk(opts, klass, *args, **kwargs): def function_get_in_bulk(opts, klass, *args, **kwargs):
id_list = args and args[0] or kwargs['id_list'] id_list = args and args[0] or kwargs['id_list']
assert id_list != [], "get_in_bulk() cannot be passed an empty list." assert id_list != [], "get_in_bulk() cannot be passed an empty list."
kwargs['where'] = ["%s.id IN (%s)" % (opts.db_table, ",".join(map(str, id_list)))] kwargs['where'] = ["%s.%s IN (%s)" % (opts.db_table, opts.pk.column, ",".join(['%s'] * len(id_list)))]
kwargs['params'] = id_list
obj_list = function_get_list(opts, klass, **kwargs) obj_list = function_get_list(opts, klass, **kwargs)
return dict([(o.id, o) for o in obj_list]) return dict([(getattr(o, opts.pk.column), o) for o in obj_list])
def function_get_latest(opts, klass, does_not_exist_exception, **kwargs): def function_get_latest(opts, klass, does_not_exist_exception, **kwargs):
kwargs['order_by'] = ('-' + opts.get_latest_by,) kwargs['order_by'] = ('-' + opts.get_latest_by,)

View File

@ -1,6 +1,7 @@
# Wrapper for loading templates from "template" directories in installed app packages. # Wrapper for loading templates from "template" directories in installed app packages.
from django.conf.settings import INSTALLED_APPS, TEMPLATE_FILE_EXTENSION from django.conf.settings import INSTALLED_APPS, TEMPLATE_FILE_EXTENSION
from django.core.exceptions import ImproperlyConfigured
from django.core.template import TemplateDoesNotExist from django.core.template import TemplateDoesNotExist
import os import os
@ -8,8 +9,17 @@ import os
app_template_dirs = [] app_template_dirs = []
for app in INSTALLED_APPS: for app in INSTALLED_APPS:
i = app.rfind('.') i = app.rfind('.')
if i == -1:
m, a = app, None
else:
m, a = app[:i], app[i+1:] m, a = app[:i], app[i+1:]
try:
if a is None:
mod = __import__(m, '', '', [])
else:
mod = getattr(__import__(m, '', '', [a]), a) mod = getattr(__import__(m, '', '', [a]), a)
except ImportError, e:
raise ImproperlyConfigured, 'ImportError %s: %s' % (app, e.args[0])
template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates') template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates')
if os.path.isdir(template_dir): if os.path.isdir(template_dir):
app_template_dirs.append(template_dir) app_template_dirs.append(template_dir)

View File

@ -12,8 +12,9 @@ Usage:
""" """
from django.utils.dates import MONTHS, MONTHS_AP, WEEKDAYS from django.utils.dates import MONTHS, MONTHS_AP, WEEKDAYS
from django.utils.tzinfo import LocalTimezone
from calendar import isleap from calendar import isleap
import re import re, time
re_formatchars = re.compile(r'(?<!\\)([aABdDfFgGhHiIjlLmMnNOPrsStTUwWyYzZ])') re_formatchars = re.compile(r'(?<!\\)([aABdDfFgGhHiIjlLmMnNOPrsStTUwWyYzZ])')
re_escaped = re.compile(r'\\(.)') re_escaped = re.compile(r'\\(.)')
@ -40,7 +41,9 @@ class TimeFormat(Formatter):
def A(self): def A(self):
"'AM' or 'PM'" "'AM' or 'PM'"
return self.a().upper() if self.data.hour > 11:
return 'PM'
return 'AM'
def B(self): def B(self):
"Swatch Internet time" "Swatch Internet time"
@ -100,8 +103,12 @@ class TimeFormat(Formatter):
class DateFormat(TimeFormat): class DateFormat(TimeFormat):
year_days = [None, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334] year_days = [None, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]
def __init__(self, d): def __init__(self, dt):
self.data = d # Accepts either a datetime or date object.
self.data = dt
self.timezone = getattr(dt, 'tzinfo', None)
if hasattr(self.data, 'hour') and not self.timezone:
self.timezone = LocalTimezone(dt)
def d(self): def d(self):
"Day of the month, 2 digits with leading zeros; i.e. '01' to '31'" "Day of the month, 2 digits with leading zeros; i.e. '01' to '31'"
@ -119,6 +126,13 @@ class DateFormat(TimeFormat):
"'1' if Daylight Savings Time, '0' otherwise." "'1' if Daylight Savings Time, '0' otherwise."
raise NotImplementedError raise NotImplementedError
def I(self):
"'1' if Daylight Savings Time, '0' otherwise."
if self.timezone.dst(self.data):
return '1'
else:
return '0'
def j(self): def j(self):
"Day of the month without leading zeros; i.e. '1' to '31'" "Day of the month without leading zeros; i.e. '1' to '31'"
return self.data.day return self.data.day
@ -149,11 +163,12 @@ class DateFormat(TimeFormat):
def O(self): def O(self):
"Difference to Greenwich time in hours; e.g. '+0200'" "Difference to Greenwich time in hours; e.g. '+0200'"
raise NotImplementedError tz = self.timezone.utcoffset(self.data)
return "%+03d%02d" % (tz.seconds // 3600, (tz.seconds // 60) % 60)
def r(self): def r(self):
"RFC 822 formatted date; e.g. 'Thu, 21 Dec 2000 16:01:07 +0200'" "RFC 822 formatted date; e.g. 'Thu, 21 Dec 2000 16:01:07 +0200'"
raise NotImplementedError return self.format('D, j M Y H:i:s O')
def S(self): def S(self):
"English ordinal suffix for the day of the month, 2 characters; i.e. 'st', 'nd', 'rd' or 'th'" "English ordinal suffix for the day of the month, 2 characters; i.e. 'st', 'nd', 'rd' or 'th'"
@ -174,11 +189,15 @@ class DateFormat(TimeFormat):
def T(self): def T(self):
"Time zone of this machine; e.g. 'EST' or 'MDT'" "Time zone of this machine; e.g. 'EST' or 'MDT'"
raise NotImplementedError name = self.timezone.tzname(self.data)
if name is None:
name = self.format('O')
return name
def U(self): def U(self):
"Seconds since the Unix epoch (January 1 1970 00:00:00 GMT)" "Seconds since the Unix epoch (January 1 1970 00:00:00 GMT)"
raise NotImplementedError off = self.timezone.utcoffset(self.data)
return int(time.mktime(self.data.timetuple())) + off.seconds * 60
def w(self): def w(self):
"Day of the week, numeric, i.e. '0' (Sunday) to '6' (Saturday)" "Day of the week, numeric, i.e. '0' (Sunday) to '6' (Saturday)"
@ -229,7 +248,7 @@ class DateFormat(TimeFormat):
"""Time zone offset in seconds (i.e. '-43200' to '43200'). The offset """Time zone offset in seconds (i.e. '-43200' to '43200'). The offset
for timezones west of UTC is always negative, and for those east of UTC for timezones west of UTC is always negative, and for those east of UTC
is always positive.""" is always positive."""
raise NotImplementedError return self.timezone.utcoffset(self.data).seconds
def format(value, format_string): def format(value, format_string):
"Convenience function" "Convenience function"

View File

@ -1,4 +1,5 @@
import time, math, datetime import datetime, math, time
from django.utils.tzinfo import LocalTimezone
def timesince(d, now=None): def timesince(d, now=None):
""" """
@ -6,7 +7,6 @@ def timesince(d, now=None):
as a nicely formatted string, e.g "10 minutes" as a nicely formatted string, e.g "10 minutes"
Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since
""" """
original = time.mktime(d.timetuple())
chunks = ( chunks = (
(60 * 60 * 24 * 365, 'year'), (60 * 60 * 24 * 365, 'year'),
(60 * 60 * 24 * 30, 'month'), (60 * 60 * 24 * 30, 'month'),
@ -14,9 +14,17 @@ def timesince(d, now=None):
(60 * 60, 'hour'), (60 * 60, 'hour'),
(60, 'minute') (60, 'minute')
) )
if not now: if now:
now = time.time() t = time.mktime(now)
since = now - original else:
t = time.localtime()
if d.tzinfo:
tz = LocalTimezone()
else:
tz = None
now = datetime.datetime(t[0], t[1], t[2], t[3], t[4], t[5], tzinfo=tz)
delta = now - d
since = delta.days * 24 * 60 * 60 + delta.seconds
# Crazy iteration syntax because we need i to be current index # Crazy iteration syntax because we need i to be current index
for i, (seconds, name) in zip(range(len(chunks)), chunks): for i, (seconds, name) in zip(range(len(chunks)), chunks):
count = math.floor(since / seconds) count = math.floor(since / seconds)

52
django/utils/tzinfo.py Normal file
View File

@ -0,0 +1,52 @@
"Implementation of tzinfo classes for use with datetime.datetime."
import time
from datetime import timedelta, tzinfo
class FixedOffset(tzinfo):
"Fixed offset in minutes east from UTC."
def __init__(self, offset):
self.__offset = timedelta(minutes=offset)
self.__name = "%+03d%02d" % (offset // 60, offset % 60)
def __repr__(self):
return self.__name
def utcoffset(self, dt):
return self.__offset
def tzname(self, dt):
return self.__name
def dst(self, dt):
return timedelta(0)
class LocalTimezone(tzinfo):
"Proxy timezone information from time module."
def __init__(self, dt):
tzinfo.__init__(self, dt)
self._tzname = time.tzname[self._isdst(dt)]
def __repr__(self):
return self._tzname
def utcoffset(self, dt):
if self._isdst(dt):
return timedelta(seconds=-time.altzone)
else:
return timedelta(seconds=-time.timezone)
def dst(self, dt):
if self._isdst(dt):
return timedelta(seconds=-time.altzone) - timedelta(seconds=-time.timezone)
else:
return timedelta(0)
def tzname(self, dt):
return time.tzname[self._isdst(dt)]
def _isdst(self, dt):
tt = (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.weekday(), 0, -1)
stamp = time.mktime(tt)
tt = time.localtime(stamp)
return tt.tm_isdst > 0

View File

@ -1,12 +1,19 @@
def user_passes_test(view_func, test_func):
"""
Decorator for views that checks that the user passes the given test,
redirecting to the log-in page if necessary. The test should be a callable
that takes the user object and returns True if the user passes.
"""
from django.views.auth.login import redirect_to_login
def _checklogin(request, *args, **kwargs):
if test_func(request.user):
return view_func(request, *args, **kwargs)
return redirect_to_login(request.path)
return _checklogin
def login_required(view_func): def login_required(view_func):
""" """
Decorator for views that checks that the user is logged in, redirecting Decorator for views that checks that the user is logged in, redirecting
to the log-in page if necessary. to the log-in page if necessary.
""" """
from django.views.auth.login import redirect_to_login return user_passes_test(lambda u: not u.is_anonymous())
def _checklogin(request, *args, **kwargs):
if request.user.is_anonymous():
return redirect_to_login(request.path)
else:
return view_func(request, *args, **kwargs)
return _checklogin

288
docs/authentication.txt Normal file
View File

@ -0,0 +1,288 @@
=============================
User authentication in Django
=============================
Django comes with a user authentication system. It handles user accounts,
groups, permissions and cookie-based user sessions. This document explains how
things work.
The basics
==========
Django supports authentication out of the box. The ``django-admin.py init``
command, used to initialize a database with Django's core database tables,
creates the infrastructure for the auth system. You don't have to do anything
else to use authentication.
The auth system consists of:
* Users
* Permissions: Binary (yes/no) flags designating whether a user may perform
a certain task.
* Groups: A generic way of applying labels and permissions to more than one
user.
* Messages: A simple way to queue messages for given users.
Users
=====
Users are represented by a standard Django model, which lives in
`django/models/auth.py`_.
.. _django/models/auth.py: http://code.djangoproject.com/browser/django/trunk/django/models/auth.py
API reference
-------------
Fields
~~~~~~
``User`` objects have the following fields:
* ``username`` -- Required. 30 characters or fewer. Alphanumeric characters
only (letters, digits and underscores).
* ``first_name`` -- Optional. 30 characters or fewer.
* ``last_name`` -- Optional. 30 characters or fewer.
* ``email`` -- Optional. E-mail address.
* ``password_md5`` -- Required. An MD5 hash of the password. (Django
doesn't store the raw password.) Raw passwords can be arbitrarily long
and can contain any character.
* ``is_staff`` -- Boolean. Designates whether this user can access the
admin site.
* ``is_active`` -- Boolean. Designates whether this user account is valid.
Set this to ``False`` instead of deleting accounts.
* ``is_superuser`` -- Boolean. Designates whether this user has permission
to do anything (according to the permission system).
* ``last_login`` -- A datetime of the user's last login. Is set to the
current date/time by default.
* ``date_joined`` -- A datetime designating when the account was created.
Is set to the current date/time by default when the account is created.
Methods
~~~~~~~
``User`` objects have two many-to-many fields: ``groups`` and
``user_permissions``. Because of those relationships, ``User`` objects get
data-access methods like any other `Django model`_:
* ``get_group_list(**kwargs)``
* ``set_groups(id_list)``
* ``get_permission_list(**kwargs)``
* ``set_user_permissions(id_list)``
In addition to those automatic API methods, ``User`` objects have the following
methods:
* ``is_anonymous()`` -- Always returns ``False``. This is a way of
comparing ``User`` objects to anonymous users.
* ``get_full_name()`` -- Returns the ``first_name`` plus the ``last_name``,
with a space in between.
* ``set_password(raw_password)`` -- Sets the user's password to the given
raw string, taking care of the MD5 hashing. Doesn't save the ``User``
object.
* ``check_password(raw_password)`` -- Returns ``True`` if the given raw
string is the correct password for the user.
* ``get_group_permissions()`` -- Returns a list of permission strings that
the user has, through his/her groups.
* ``get_all_permissions()`` -- Returns a list of permission strings that
the user has, both through group and user permissions.
* ``has_perm(perm)`` -- Returns ``True`` if the user has the specified
permission.
* ``has_perms(perm_list)`` -- Returns ``True`` if the user has each of the
specified permissions.
* ``has_module_perms(package_name)`` -- Returns ``True`` if the user has
any permissions in the given package (the Django app label).
* ``get_and_delete_messages()`` -- Returns a list of ``Message`` objects in
the user's queue and deletes the messages from the queue.
* ``email_user(subject, message, from_email=None)`` -- Sends an e-mail to
the user. If ``from_email`` is ``None``, Django uses the
`DEFAULT_FROM_EMAIL`_ setting.
* ``get_profile()`` -- Returns a site-specific profile for this user.
Raises ``django.models.auth.SiteProfileNotAvailable`` if the current site
doesn't allow profiles.
.. _Django model: http://www.djangoproject.com/documentation/model_api/
.. _DEFAULT_FROM_EMAIL: http://www.djangoproject.com/documentation/settings/#default-from-email
Module functions
~~~~~~~~~~~~~~~~
The ``django.models.auth.users`` module has the following helper functions:
* ``create_user(username, email, password)`` -- Creates, saves and returns
a ``User``. The ``username``, ``email`` and ``password`` are set as
given, and the ``User`` gets ``is_active=True``.
* ``make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')``
-- Returns a random password with the given length and given string of
allowed characters. (Note that the default value of ``allowed_chars``
doesn't contain ``"I"`` or letters that look like it, to avoid user
confusion.
Basic usage
-----------
Creating users
~~~~~~~~~~~~~~
The most basic way to create users is to use the standard Django
`database API`_. Just create and save a ``User`` object::
>>> from django.models.auth import users
>>> import md5
>>> p = md5.new('johnpassword').hexdigest()
>>> u = users.User(username='john', first_name='John', last_name='lennon',
... email='lennon@thebeatles.com', password_md5=p, is_staff=True,
... is_active=True, is_superuser=False)
>>> u.save()
Note that ``password_md5`` requires the raw MD5 hash. Because that's a pain,
there's a ``create_user`` helper function::
>>> from django.models.auth import users
>>> u = users.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
.. _database API: http://www.djangoproject.com/documentation/db_api/
Changing passwords
~~~~~~~~~~~~~~~~~~
Change a password with ``set_password()``::
>>> from django.models.auth import users
>>> u = users.get_object(username__exact='john')
>>> u.set_password('new password')
>>> u.save()
Anonymous users
---------------
``django.parts.auth.anonymoususers.AnonymousUser`` is a class that implements
the ``django.models.auth.users.User`` interface, with these differences:
* ``is_anonymous()`` returns ``True`` instead of ``False``.
* ``has_perm()`` always returns ``False``.
* ``set_password()``, ``check_password()``, ``set_groups()`` and
``set_permissions()`` raise ``NotImplementedError``.
In practice, you probably won't need to use ``AnonymousUser`` objects on your
own, but they're used by Web requests, as explained in the next section.
Authentication in Web requests
==============================
Until now, this document has dealt with the low-level APIs for manipulating
authentication-related objects. On a higher level, Django hooks this
authentication framework into its system of `request objects`_.
In any Django view, ``request.user`` will give you a ``User`` object
representing the currently logged-in user. If a user isn't currently logged in,
``request.user`` will be set to an instance of ``AnonymousUser`` (see the
previous section). You can tell them apart with ``is_anonymous()``, like so::
if request.user.is_anonymous():
# Do something for anonymous users.
else:
# Do something for logged-in users.
.. _request objects: http://www.djangoproject.com/documentation/request_response/#httprequest-objects
Limiting access to logged-in users
----------------------------------
The raw way
~~~~~~~~~~~
The simple, raw way to limit access to pages is to check
``request.user.is_anonymous()`` and either redirect to a login page::
from django.utils.httpwrappers import HttpResponseRedirect
def my_view(request):
if request.user.is_anonymous():
return HttpResponseRedirect('/login/?next=%s' % request.path)
# ...
...or display an error message::
def my_view(request):
if request.user.is_anonymous():
return render_to_response('myapp/login_error')
# ...
The login_required decorator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
As a shortcut, you can use the convenient ``login_required`` decorator::
from django.views.decorators.auth import login_required
def my_view(request):
# ...
my_view = login_required(my_view)
Here's the same thing, using Python 2.4's decorator syntax::
from django.views.decorators.auth import login_required
@login_required
def my_view(request):
# ...
``login_required`` does the following:
* If the user isn't logged in, redirect to ``/accounts/login/``, passing
the current absolute URL in the query string as ``next``. For example:
``/accounts/login/?next=/polls/3/``.
* If the user is logged in, execute the view normally. The view code is
free to assume the user is logged in.
Limiting access to logged-in users that pass a test
---------------------------------------------------
To limit access based on certain permissions or another test, you'd do the same
thing as described in the previous section.
The simple way is to run your test on ``request.user`` in the view directly.
For example, this view checks to make sure the user is logged in and has the
permission ``polls.can_vote``::
def my_view(request):
if request.user.is_anonymous() or not request.user.has_perm('polls.can_vote'):
return HttpResponse("You can't vote in this poll.")
# ...
As a shortcut, you can use the convenient ``user_passes_test`` decorator::
from django.views.decorators.auth import user_passes_test
@user_passes_test(lambda u: u.has_perm('polls.can_vote'))
def my_view(request):
# ...
``user_passes_test`` takes a required argument: a callable that takes a
``User`` object and returns ``True`` if the user is allowed to view the page.
Note that ``user_passes_test`` does not automatically check that the ``User``
is not anonymous.
Permissions
===========
Groups
======
Messages
========

View File

@ -517,18 +517,18 @@ Built-in tag reference
n Month without leading zeros. ``'1'`` to ``'12'`` n Month without leading zeros. ``'1'`` to ``'12'``
N Month abbreviation in Associated Press ``'Jan.'``, ``'Feb.'``, ``'March'``, ``'May'`` N Month abbreviation in Associated Press ``'Jan.'``, ``'Feb.'``, ``'March'``, ``'May'``
style. Proprietary extension. style. Proprietary extension.
O Not implemented. O Difference to Greenwich time in hours. ``'+0200'``
P Time, in 12-hour hours, minutes and ``'1 a.m.'``, ``'1:30 p.m.'``, ``'midnight'``, ``'noon'``, ``'12:30 p.m.'`` P Time, in 12-hour hours, minutes and ``'1 a.m.'``, ``'1:30 p.m.'``, ``'midnight'``, ``'noon'``, ``'12:30 p.m.'``
'a.m.'/'p.m.', with minutes left off 'a.m.'/'p.m.', with minutes left off
if they're zero and the special-case if they're zero and the special-case
strings 'midnight' and 'noon' if strings 'midnight' and 'noon' if
appropriate. Proprietary extension. appropriate. Proprietary extension.
r Not implemented. r RFC 822 formatted date. ``'Thu, 21 Dec 2000 16:01:07 +0200'``
s Seconds, 2 digits with leading zeros. ``'00'`` to ``'59'`` s Seconds, 2 digits with leading zeros. ``'00'`` to ``'59'``
S English ordinal suffix for day of the ``'st'``, ``'nd'``, ``'rd'`` or ``'th'`` S English ordinal suffix for day of the ``'st'``, ``'nd'``, ``'rd'`` or ``'th'``
month, 2 characters. month, 2 characters.
t Not implemented. t Not implemented.
T Not implemented. T Time zone of this machine. ``'EST'``, ``'MDT'``
U Not implemented. U Not implemented.
w Day of the week, digits without ``'0'`` (Sunday) to ``'6'`` (Saturday) w Day of the week, digits without ``'0'`` (Sunday) to ``'6'`` (Saturday)
leading zeros. leading zeros.
@ -537,7 +537,10 @@ Built-in tag reference
y Year, 2 digits. ``'99'`` y Year, 2 digits. ``'99'``
Y Year, 4 digits. ``'1999'`` Y Year, 4 digits. ``'1999'``
z Day of the year. ``0`` to ``365`` z Day of the year. ``0`` to ``365``
Z Not implemented. Z Time zone offset in seconds. The ``-43200`` to ``43200``
offset for timezones west of UTC is
always negative, and for those east of
UTC is always positive.
================ ====================================== ===================== ================ ====================================== =====================
Example:: Example::
@ -610,6 +613,11 @@ Built-in tag reference
{% ssi /home/html/ljworld.com/includes/right_generic.html parsed %} {% ssi /home/html/ljworld.com/includes/right_generic.html parsed %}
Note that if you use ``{% ssi %}``, you'll need to define
`ALLOWED_INCLUDE_ROOTS`_ in your Django settings, as a security measure.
.. _ALLOWED_INCLUDE_ROOTS: http://www.djangoproject.com/documentation/settings/#allowed-include-roots
``templatetag`` ``templatetag``
Output one of the bits used to compose template tags. Output one of the bits used to compose template tags.

View File

@ -0,0 +1,75 @@
"""
>>> format(my_birthday, '')
''
>>> format(my_birthday, 'a')
'p.m.'
>>> format(my_birthday, 'A')
'PM'
>>> format(my_birthday, 'j')
'7'
>>> format(my_birthday, 'l')
'Saturday'
>>> format(my_birthday, 'L')
'False'
>>> format(my_birthday, 'm')
'07'
>>> format(my_birthday, 'M')
'Jul'
>>> format(my_birthday, 'n')
'7'
>>> format(my_birthday, 'N')
'July'
>>> format(my_birthday, 'O')
'+0100'
>>> format(my_birthday, 'P')
'10 p.m.'
>>> format(my_birthday, 'r')
'Sat, 7 Jul 1979 22:00:00 +0100'
>>> format(my_birthday, 's')
'00'
>>> format(my_birthday, 'S')
'th'
>>> format(my_birthday, 't')
Traceback (most recent call last):
...
NotImplementedError
>>> format(my_birthday, 'T')
'CET'
>>> format(my_birthday, 'U')
'300445200'
>>> format(my_birthday, 'w')
'6'
>>> format(my_birthday, 'W')
'27'
>>> format(my_birthday, 'y')
'79'
>>> format(my_birthday, 'Y')
'1979'
>>> format(my_birthday, 'z')
'188'
>>> format(my_birthday, 'Z')
'3600'
>>> format(summertime, 'I')
'1'
>>> format(summertime, 'O')
'+0200'
>>> format(wintertime, 'I')
'0'
>>> format(wintertime, 'O')
'+0100'
>>> format(my_birthday, 'Y z \\C\\E\\T')
'1979 188 CET'
"""
from django.utils import dateformat
format = dateformat.format
import datetime, os, time
os.environ['TZ'] = 'Europe/Copenhagen'
time.tzset()
my_birthday = datetime.datetime(1979, 7, 7, 22, 00)
summertime = datetime.datetime(2005, 10, 30, 1, 00)
wintertime = datetime.datetime(2005, 10, 30, 4, 00)

View File

@ -53,6 +53,8 @@ EmployeeDoesNotExist: Employee does not exist for {'pk': 'foo'}
>>> fran.save() >>> fran.save()
>>> employees.get_list(last_name__exact='Jones') >>> employees.get_list(last_name__exact='Jones')
[Dan Jones, Fran Jones] [Dan Jones, Fran Jones]
>>> employees.get_in_bulk(['ABC123', 'XYZ456'])
{'XYZ456': Fran Jones, 'ABC123': Dan Jones}
>>> b = businesses.Business(name='Sears') >>> b = businesses.Business(name='Sears')
>>> b.save() >>> b.save()
@ -62,4 +64,6 @@ True
[Dan Jones, Fran Jones] [Dan Jones, Fran Jones]
>>> fran.get_business_list() >>> fran.get_business_list()
[Sears] [Sears]
>>> businesses.get_in_bulk(['Sears'])
{'Sears': Sears}
""" """