mirror of
https://github.com/django/django.git
synced 2025-07-04 09:49:12 +00:00
unicode: Merged from trunk up to [5080].
git-svn-id: http://code.djangoproject.com/svn/django/branches/unicode@5081 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
dfe20bb91a
commit
dfc553625d
3
AUTHORS
3
AUTHORS
@ -49,6 +49,7 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
ant9000@netwise.it
|
ant9000@netwise.it
|
||||||
David Ascher <http://ascher.ca/>
|
David Ascher <http://ascher.ca/>
|
||||||
Arthur <avandorp@gmail.com>
|
Arthur <avandorp@gmail.com>
|
||||||
|
axiak@mit.edu
|
||||||
Jiri Barton
|
Jiri Barton
|
||||||
Ned Batchelder <http://www.nedbatchelder.com/>
|
Ned Batchelder <http://www.nedbatchelder.com/>
|
||||||
Shannon -jj Behrens <http://jjinux.blogspot.com/>
|
Shannon -jj Behrens <http://jjinux.blogspot.com/>
|
||||||
@ -84,6 +85,7 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
Jeremy Dunck <http://dunck.us/>
|
Jeremy Dunck <http://dunck.us/>
|
||||||
Andy Dustman <farcepest@gmail.com>
|
Andy Dustman <farcepest@gmail.com>
|
||||||
Clint Ecker
|
Clint Ecker
|
||||||
|
enlight
|
||||||
Enrico <rico.bl@gmail.com>
|
Enrico <rico.bl@gmail.com>
|
||||||
Ludvig Ericson <ludvig.ericson@gmail.com>
|
Ludvig Ericson <ludvig.ericson@gmail.com>
|
||||||
Dirk Eschler <dirk.eschler@gmx.net>
|
Dirk Eschler <dirk.eschler@gmx.net>
|
||||||
@ -108,6 +110,7 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
hipertracker@gmail.com
|
hipertracker@gmail.com
|
||||||
Ian Holsman <http://feh.holsman.net/>
|
Ian Holsman <http://feh.holsman.net/>
|
||||||
Kieran Holland <http://www.kieranholland.com>
|
Kieran Holland <http://www.kieranholland.com>
|
||||||
|
Sung-Jin Hong <serialx.net@gmail.com>
|
||||||
Robert Rock Howard <http://djangomojo.com/>
|
Robert Rock Howard <http://djangomojo.com/>
|
||||||
Jason Huggins <http://www.jrandolph.com/blog/>
|
Jason Huggins <http://www.jrandolph.com/blog/>
|
||||||
Hyun Mi Ae
|
Hyun Mi Ae
|
||||||
|
@ -315,6 +315,12 @@ BANNED_IPS = ()
|
|||||||
|
|
||||||
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
|
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
|
||||||
|
|
||||||
|
LOGIN_URL = '/accounts/login/'
|
||||||
|
|
||||||
|
LOGOUT_URL = '/accounts/logout/'
|
||||||
|
|
||||||
|
LOGIN_REDIRECT_URL = '/accounts/profile/'
|
||||||
|
|
||||||
###########
|
###########
|
||||||
# TESTING #
|
# TESTING #
|
||||||
###########
|
###########
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -90,8 +90,6 @@ def staff_member_required(view_func):
|
|||||||
if user.is_active and user.is_staff:
|
if user.is_active and user.is_staff:
|
||||||
login(request, user)
|
login(request, user)
|
||||||
# TODO: set last_login with an event.
|
# TODO: set last_login with an event.
|
||||||
user.last_login = datetime.datetime.now()
|
|
||||||
user.save()
|
|
||||||
if request.POST.has_key('post_data'):
|
if request.POST.has_key('post_data'):
|
||||||
post_data = _decode_post_data(request.POST['post_data'])
|
post_data = _decode_post_data(request.POST['post_data'])
|
||||||
if post_data and not post_data.has_key(LOGIN_FORM_KEY):
|
if post_data and not post_data.has_key(LOGIN_FORM_KEY):
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
import datetime
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
|
||||||
SESSION_KEY = '_auth_user_id'
|
SESSION_KEY = '_auth_user_id'
|
||||||
BACKEND_SESSION_KEY = '_auth_user_backend'
|
BACKEND_SESSION_KEY = '_auth_user_backend'
|
||||||
LOGIN_URL = '/accounts/login/'
|
|
||||||
REDIRECT_FIELD_NAME = 'next'
|
REDIRECT_FIELD_NAME = 'next'
|
||||||
|
|
||||||
def load_backend(path):
|
def load_backend(path):
|
||||||
@ -49,6 +49,8 @@ def login(request, user):
|
|||||||
if user is None:
|
if user is None:
|
||||||
user = request.user
|
user = request.user
|
||||||
# TODO: It would be nice to support different login methods, like signed cookies.
|
# TODO: It would be nice to support different login methods, like signed cookies.
|
||||||
|
user.last_login = datetime.datetime.now()
|
||||||
|
user.save()
|
||||||
request.session[SESSION_KEY] = user.id
|
request.session[SESSION_KEY] = user.id
|
||||||
request.session[BACKEND_SESSION_KEY] = user.backend
|
request.session[BACKEND_SESSION_KEY] = user.backend
|
||||||
|
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
from django.contrib.auth import LOGIN_URL, REDIRECT_FIELD_NAME
|
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from urllib import quote
|
from urllib import quote
|
||||||
|
|
||||||
def user_passes_test(test_func, login_url=LOGIN_URL):
|
def user_passes_test(test_func, login_url=None):
|
||||||
"""
|
"""
|
||||||
Decorator for views that checks that the user passes the given test,
|
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
|
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.
|
that takes the user object and returns True if the user passes.
|
||||||
"""
|
"""
|
||||||
|
if not login_url:
|
||||||
|
from django.conf import settings
|
||||||
|
login_url = settings.LOGIN_URL
|
||||||
def _dec(view_func):
|
def _dec(view_func):
|
||||||
def _checklogin(request, *args, **kwargs):
|
def _checklogin(request, *args, **kwargs):
|
||||||
if test_func(request.user):
|
if test_func(request.user):
|
||||||
@ -27,7 +30,7 @@ login_required.__doc__ = (
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
def permission_required(perm, login_url=LOGIN_URL):
|
def permission_required(perm, login_url=None):
|
||||||
"""
|
"""
|
||||||
Decorator for views that checks whether a user has a particular permission
|
Decorator for views that checks whether a user has a particular permission
|
||||||
enabled, redirecting to the log-in page if necessary.
|
enabled, redirecting to the log-in page if necessary.
|
||||||
|
@ -2,7 +2,7 @@ from django.core import validators
|
|||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.db import backend, connection, models
|
from django.db import backend, connection, models
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import ugettext_lazy
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
def check_password(raw_password, enc_password):
|
def check_password(raw_password, enc_password):
|
||||||
@ -17,6 +17,12 @@ def check_password(raw_password, enc_password):
|
|||||||
elif algo == 'sha1':
|
elif algo == 'sha1':
|
||||||
import sha
|
import sha
|
||||||
return hsh == sha.new(salt+raw_password).hexdigest()
|
return hsh == sha.new(salt+raw_password).hexdigest()
|
||||||
|
elif algo == 'crypt':
|
||||||
|
try:
|
||||||
|
import crypt
|
||||||
|
except ImportError:
|
||||||
|
raise ValueError, "Crypt password algorithm not supported in this environment."
|
||||||
|
return hsh == crypt.crypt(raw_password, salt)
|
||||||
raise ValueError, "Got unknown password algorithm type in password."
|
raise ValueError, "Got unknown password algorithm type in password."
|
||||||
|
|
||||||
class SiteProfileNotAvailable(Exception):
|
class SiteProfileNotAvailable(Exception):
|
||||||
@ -273,7 +279,7 @@ class AnonymousUser(object):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u'AnonymousUser'
|
return ugettext_lazy('AnonymousUser')
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return isinstance(other, self.__class__)
|
return isinstance(other, self.__class__)
|
||||||
|
@ -6,7 +6,7 @@ from django.template import RequestContext
|
|||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth import LOGIN_URL, REDIRECT_FIELD_NAME
|
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||||||
|
|
||||||
def login(request, template_name='registration/login.html'):
|
def login(request, template_name='registration/login.html'):
|
||||||
"Displays the login form and handles the login action."
|
"Displays the login form and handles the login action."
|
||||||
@ -17,7 +17,8 @@ def login(request, template_name='registration/login.html'):
|
|||||||
if not errors:
|
if not errors:
|
||||||
# Light security check -- make sure redirect_to isn't garbage.
|
# Light security check -- make sure redirect_to isn't garbage.
|
||||||
if not redirect_to or '://' in redirect_to or ' ' in redirect_to:
|
if not redirect_to or '://' in redirect_to or ' ' in redirect_to:
|
||||||
redirect_to = '/accounts/profile/'
|
from django.conf import settings
|
||||||
|
redirect_to = settings.LOGIN_REDIRECT_URL
|
||||||
from django.contrib.auth import login
|
from django.contrib.auth import login
|
||||||
login(request, manipulator.get_user())
|
login(request, manipulator.get_user())
|
||||||
request.session.delete_test_cookie()
|
request.session.delete_test_cookie()
|
||||||
@ -41,12 +42,18 @@ def logout(request, next_page=None, template_name='registration/logged_out.html'
|
|||||||
# Redirect to this page until the session has been cleared.
|
# Redirect to this page until the session has been cleared.
|
||||||
return HttpResponseRedirect(next_page or request.path)
|
return HttpResponseRedirect(next_page or request.path)
|
||||||
|
|
||||||
def logout_then_login(request, login_url=LOGIN_URL):
|
def logout_then_login(request, login_url=None):
|
||||||
"Logs out the user if he is logged in. Then redirects to the log-in page."
|
"Logs out the user if he is logged in. Then redirects to the log-in page."
|
||||||
|
if not login_url:
|
||||||
|
from django.conf import settings
|
||||||
|
login_url = settings.LOGIN_URL
|
||||||
return logout(request, login_url)
|
return logout(request, login_url)
|
||||||
|
|
||||||
def redirect_to_login(next, login_url=LOGIN_URL):
|
def redirect_to_login(next, login_url=None):
|
||||||
"Redirects the user to the login page, passing the given 'next' page"
|
"Redirects the user to the login page, passing the given 'next' page"
|
||||||
|
if not login_url:
|
||||||
|
from django.conf import settings
|
||||||
|
login_url = settings.LOGIN_URL
|
||||||
return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, next))
|
return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, next))
|
||||||
|
|
||||||
def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html',
|
def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html',
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<form {% if photos_optional or photos_required %}enctype="multipart/form-data" {% endif %}action="/comments/post/" method="post">
|
<form {% if photos_optional or photos_required %}enctype="multipart/form-data" {% endif %}action="/comments/post/" method="post">
|
||||||
|
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
<p>{% trans "Username:" %} <strong>{{ user.username }}</strong> (<a href="/accounts/logout/">{% trans "Log out" %}</a>)</p>
|
<p>{% trans "Username:" %} <strong>{{ user.username }}</strong> (<a href="{{ logout_url }}">{% trans "Log out" %}</a>)</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p><label for="id_username">{% trans "Username:" %}</label> <input type="text" name="username" id="id_username" /><br />{% trans "Password:" %} <input type="password" name="password" id="id_password" /> (<a href="/accounts/password_reset/">{% trans "Forgotten your password?" %}</a>)</p>
|
<p><label for="id_username">{% trans "Username:" %}</label> <input type="text" name="username" id="id_username" /><br />{% trans "Password:" %} <input type="password" name="password" id="id_password" /> (<a href="/accounts/password_reset/">{% trans "Forgotten your password?" %}</a>)</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -25,6 +25,7 @@ class CommentFormNode(template.Node):
|
|||||||
self.is_public = is_public
|
self.is_public = is_public
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
|
from django.conf import settings
|
||||||
from django.utils.text import normalize_newlines
|
from django.utils.text import normalize_newlines
|
||||||
import base64
|
import base64
|
||||||
context.push()
|
context.push()
|
||||||
@ -64,6 +65,7 @@ class CommentFormNode(template.Node):
|
|||||||
if self.rating_options:
|
if self.rating_options:
|
||||||
context['rating_range'], context['rating_choices'] = Comment.objects.get_rating_options(self.rating_options)
|
context['rating_range'], context['rating_choices'] = Comment.objects.get_rating_options(self.rating_options)
|
||||||
context['hash'] = Comment.objects.get_security_hash(context['options'], context['photo_options'], context['rating_options'], context['target'])
|
context['hash'] = Comment.objects.get_security_hash(context['options'], context['photo_options'], context['rating_options'], context['target'])
|
||||||
|
context['logout_url'] = settings.LOGOUT_URL
|
||||||
default_form = loader.get_template(COMMENT_FORM)
|
default_form = loader.get_template(COMMENT_FORM)
|
||||||
output = default_form.render(context)
|
output = default_form.render(context)
|
||||||
context.pop()
|
context.pop()
|
||||||
|
0
django/contrib/localflavor/is_/__init__.py
Normal file
0
django/contrib/localflavor/is_/__init__.py
Normal file
81
django/contrib/localflavor/is_/forms.py
Normal file
81
django/contrib/localflavor/is_/forms.py
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
"""
|
||||||
|
Iceland specific form helpers.
|
||||||
|
"""
|
||||||
|
from django.newforms import ValidationError
|
||||||
|
from django.newforms.fields import RegexField, EMPTY_VALUES
|
||||||
|
from django.newforms.widgets import Select
|
||||||
|
from django.utils.translation import gettext
|
||||||
|
|
||||||
|
|
||||||
|
class ISIdNumberField(RegexField):
|
||||||
|
"""
|
||||||
|
Icelandic identification number (kennitala). This is a number every citizen
|
||||||
|
of Iceland has.
|
||||||
|
"""
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
error_msg = gettext(u'Enter a valid Icelandic identification number. The format is XXXXXX-XXXX.')
|
||||||
|
kwargs['min_length'],kwargs['max_length'] = 10,11
|
||||||
|
|
||||||
|
super(ISIdNumberField, self).__init__(r'^\d{6}(-| )?\d{4}$', error_message=error_msg, *args, **kwargs)
|
||||||
|
|
||||||
|
def clean(self, value):
|
||||||
|
value = super(ISIdNumberField, self).clean(value)
|
||||||
|
|
||||||
|
if value in EMPTY_VALUES:
|
||||||
|
return u''
|
||||||
|
|
||||||
|
value = self._canonify(value)
|
||||||
|
if self._validate(value):
|
||||||
|
return self._format(value)
|
||||||
|
else:
|
||||||
|
raise ValidationError(gettext(u'The Icelandic identification number is not valid.'))
|
||||||
|
|
||||||
|
|
||||||
|
def _canonify(self, value):
|
||||||
|
"""
|
||||||
|
Returns the value as only digits.
|
||||||
|
"""
|
||||||
|
return value.replace('-', '').replace(' ', '')
|
||||||
|
|
||||||
|
def _validate(self, value):
|
||||||
|
"""
|
||||||
|
Takes in the value in canonical form and checks the verifier digit. The
|
||||||
|
method is modulo 11.
|
||||||
|
"""
|
||||||
|
check = [3, 2, 7, 6, 5, 4, 3, 2, 1, 0]
|
||||||
|
return sum(int(value[i]) * check[i] for i in range(10)) % 11 == 0
|
||||||
|
|
||||||
|
def _format(self, value):
|
||||||
|
"""
|
||||||
|
Takes in the value in canonical form and returns it in the common
|
||||||
|
display format.
|
||||||
|
"""
|
||||||
|
return value[:6]+'-'+value[6:]
|
||||||
|
|
||||||
|
|
||||||
|
class ISPhoneNumberField(RegexField):
|
||||||
|
"""
|
||||||
|
Icelandic phone number. Seven digits with an optional hyphen or space after
|
||||||
|
the first three digits.
|
||||||
|
"""
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
kwargs['min_length'], kwargs['max_length'] = 7,8
|
||||||
|
super(ISPhoneNumberField, self).__init__(r'^\d{3}(-| )?\d{4}$', *args, **kwargs)
|
||||||
|
|
||||||
|
def clean(self, value):
|
||||||
|
value = super(ISPhoneNumberField, self).clean(value)
|
||||||
|
|
||||||
|
if value in EMPTY_VALUES:
|
||||||
|
return u''
|
||||||
|
|
||||||
|
return value.replace('-', '').replace(' ', '')
|
||||||
|
|
||||||
|
|
||||||
|
class ISPostalCodeSelect(Select):
|
||||||
|
"""
|
||||||
|
A Select widget that uses a list of Icelandic postal codes as its choices.
|
||||||
|
"""
|
||||||
|
def __init__(self, attrs=None):
|
||||||
|
from is_postalcodes import IS_POSTALCODES
|
||||||
|
super(ISPostalCodeSelect, self).__init__(attrs, choices=IS_POSTALCODES)
|
||||||
|
|
151
django/contrib/localflavor/is_/is_postalcodes.py
Normal file
151
django/contrib/localflavor/is_/is_postalcodes.py
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
IS_POSTALCODES = (
|
||||||
|
('101', u'101 Reykjavík'),
|
||||||
|
('103', u'103 Reykjavík'),
|
||||||
|
('104', u'104 Reykjavík'),
|
||||||
|
('105', u'105 Reykjavík'),
|
||||||
|
('107', u'107 Reykjavík'),
|
||||||
|
('108', u'108 Reykjavík'),
|
||||||
|
('109', u'109 Reykjavík'),
|
||||||
|
('110', u'110 Reykjavík'),
|
||||||
|
('111', u'111 Reykjavík'),
|
||||||
|
('112', u'112 Reykjavík'),
|
||||||
|
('113', u'113 Reykjavík'),
|
||||||
|
('116', u'116 Kjalarnes'),
|
||||||
|
('121', u'121 Reykjavík'),
|
||||||
|
('123', u'123 Reykjavík'),
|
||||||
|
('124', u'124 Reykjavík'),
|
||||||
|
('125', u'125 Reykjavík'),
|
||||||
|
('127', u'127 Reykjavík'),
|
||||||
|
('128', u'128 Reykjavík'),
|
||||||
|
('129', u'129 Reykjavík'),
|
||||||
|
('130', u'130 Reykjavík'),
|
||||||
|
('132', u'132 Reykjavík'),
|
||||||
|
('150', u'150 Reykjavík'),
|
||||||
|
('155', u'155 Reykjavík'),
|
||||||
|
('170', u'170 Seltjarnarnes'),
|
||||||
|
('172', u'172 Seltjarnarnes'),
|
||||||
|
('190', u'190 Vogar'),
|
||||||
|
('200', u'200 Kópavogur'),
|
||||||
|
('201', u'201 Kópavogur'),
|
||||||
|
('202', u'202 Kópavogur'),
|
||||||
|
('203', u'203 Kópavogur'),
|
||||||
|
('210', u'210 Garðabær'),
|
||||||
|
('212', u'212 Garðabær'),
|
||||||
|
('220', u'220 Hafnarfjörður'),
|
||||||
|
('221', u'221 Hafnarfjörður'),
|
||||||
|
('222', u'222 Hafnarfjörður'),
|
||||||
|
('225', u'225 Álftanes'),
|
||||||
|
('230', u'230 Reykjanesbær'),
|
||||||
|
('232', u'232 Reykjanesbær'),
|
||||||
|
('233', u'233 Reykjanesbær'),
|
||||||
|
('235', u'235 Keflavíkurflugvöllur'),
|
||||||
|
('240', u'240 Grindavík'),
|
||||||
|
('245', u'245 Sandgerði'),
|
||||||
|
('250', u'250 Garður'),
|
||||||
|
('260', u'260 Reykjanesbær'),
|
||||||
|
('270', u'270 Mosfellsbær'),
|
||||||
|
('300', u'300 Akranes'),
|
||||||
|
('301', u'301 Akranes'),
|
||||||
|
('302', u'302 Akranes'),
|
||||||
|
('310', u'310 Borgarnes'),
|
||||||
|
('311', u'311 Borgarnes'),
|
||||||
|
('320', u'320 Reykholt í Borgarfirði'),
|
||||||
|
('340', u'340 Stykkishólmur'),
|
||||||
|
('345', u'345 Flatey á Breiðafirði'),
|
||||||
|
('350', u'350 Grundarfjörður'),
|
||||||
|
('355', u'355 Ólafsvík'),
|
||||||
|
('356', u'356 Snæfellsbær'),
|
||||||
|
('360', u'360 Hellissandur'),
|
||||||
|
('370', u'370 Búðardalur'),
|
||||||
|
('371', u'371 Búðardalur'),
|
||||||
|
('380', u'380 Reykhólahreppur'),
|
||||||
|
('400', u'400 Ísafjörður'),
|
||||||
|
('401', u'401 Ísafjörður'),
|
||||||
|
('410', u'410 Hnífsdalur'),
|
||||||
|
('415', u'415 Bolungarvík'),
|
||||||
|
('420', u'420 Súðavík'),
|
||||||
|
('425', u'425 Flateyri'),
|
||||||
|
('430', u'430 Suðureyri'),
|
||||||
|
('450', u'450 Patreksfjörður'),
|
||||||
|
('451', u'451 Patreksfjörður'),
|
||||||
|
('460', u'460 Tálknafjörður'),
|
||||||
|
('465', u'465 Bíldudalur'),
|
||||||
|
('470', u'470 Þingeyri'),
|
||||||
|
('471', u'471 Þingeyri'),
|
||||||
|
('500', u'500 Staður'),
|
||||||
|
('510', u'510 Hólmavík'),
|
||||||
|
('512', u'512 Hólmavík'),
|
||||||
|
('520', u'520 Drangsnes'),
|
||||||
|
('522', u'522 Kjörvogur'),
|
||||||
|
('523', u'523 Bær'),
|
||||||
|
('524', u'524 Norðurfjörður'),
|
||||||
|
('530', u'530 Hvammstangi'),
|
||||||
|
('531', u'531 Hvammstangi'),
|
||||||
|
('540', u'540 Blönduós'),
|
||||||
|
('541', u'541 Blönduós'),
|
||||||
|
('545', u'545 Skagaströnd'),
|
||||||
|
('550', u'550 Sauðárkrókur'),
|
||||||
|
('551', u'551 Sauðárkrókur'),
|
||||||
|
('560', u'560 Varmahlíð'),
|
||||||
|
('565', u'565 Hofsós'),
|
||||||
|
('566', u'566 Hofsós'),
|
||||||
|
('570', u'570 Fljót'),
|
||||||
|
('580', u'580 Siglufjörður'),
|
||||||
|
('600', u'600 Akureyri'),
|
||||||
|
('601', u'601 Akureyri'),
|
||||||
|
('602', u'602 Akureyri'),
|
||||||
|
('603', u'603 Akureyri'),
|
||||||
|
('610', u'610 Grenivík'),
|
||||||
|
('611', u'611 Grímsey'),
|
||||||
|
('620', u'620 Dalvík'),
|
||||||
|
('621', u'621 Dalvík'),
|
||||||
|
('625', u'625 Ólafsfjörður'),
|
||||||
|
('630', u'630 Hrísey'),
|
||||||
|
('640', u'640 Húsavík'),
|
||||||
|
('641', u'641 Húsavík'),
|
||||||
|
('645', u'645 Fosshóll'),
|
||||||
|
('650', u'650 Laugar'),
|
||||||
|
('660', u'660 Mývatn'),
|
||||||
|
('670', u'670 Kópasker'),
|
||||||
|
('671', u'671 Kópasker'),
|
||||||
|
('675', u'675 Raufarhöfn'),
|
||||||
|
('680', u'680 Þórshöfn'),
|
||||||
|
('681', u'681 Þórshöfn'),
|
||||||
|
('685', u'685 Bakkafjörður'),
|
||||||
|
('690', u'690 Vopnafjörður'),
|
||||||
|
('700', u'700 Egilsstaðir'),
|
||||||
|
('701', u'701 Egilsstaðir'),
|
||||||
|
('710', u'710 Seyðisfjörður'),
|
||||||
|
('715', u'715 Mjóifjörður'),
|
||||||
|
('720', u'720 Borgarfjörður eystri'),
|
||||||
|
('730', u'730 Reyðarfjörður'),
|
||||||
|
('735', u'735 Eskifjörður'),
|
||||||
|
('740', u'740 Neskaupstaður'),
|
||||||
|
('750', u'750 Fáskrúðsfjörður'),
|
||||||
|
('755', u'755 Stöðvarfjörður'),
|
||||||
|
('760', u'760 Breiðdalsvík'),
|
||||||
|
('765', u'765 Djúpivogur'),
|
||||||
|
('780', u'780 Höfn í Hornafirði'),
|
||||||
|
('781', u'781 Höfn í Hornafirði'),
|
||||||
|
('785', u'785 Öræfi'),
|
||||||
|
('800', u'800 Selfoss'),
|
||||||
|
('801', u'801 Selfoss'),
|
||||||
|
('802', u'802 Selfoss'),
|
||||||
|
('810', u'810 Hveragerði'),
|
||||||
|
('815', u'815 Þorlákshöfn'),
|
||||||
|
('820', u'820 Eyrarbakki'),
|
||||||
|
('825', u'825 Stokkseyri'),
|
||||||
|
('840', u'840 Laugarvatn'),
|
||||||
|
('845', u'845 Flúðir'),
|
||||||
|
('850', u'850 Hella'),
|
||||||
|
('851', u'851 Hella'),
|
||||||
|
('860', u'860 Hvolsvöllur'),
|
||||||
|
('861', u'861 Hvolsvöllur'),
|
||||||
|
('870', u'870 Vík'),
|
||||||
|
('871', u'871 Vík'),
|
||||||
|
('880', u'880 Kirkjubæjarklaustur'),
|
||||||
|
('900', u'900 Vestmannaeyjar'),
|
||||||
|
('902', u'902 Vestmannaeyjar')
|
||||||
|
)
|
@ -105,9 +105,11 @@ class Serializer(object):
|
|||||||
|
|
||||||
def getvalue(self):
|
def getvalue(self):
|
||||||
"""
|
"""
|
||||||
Return the fully serialized queryset.
|
Return the fully serialized queryset (or None if the output stream is
|
||||||
|
not seekable).
|
||||||
"""
|
"""
|
||||||
return self.stream.getvalue()
|
if callable(getattr(self.stream, 'getvalue', None)):
|
||||||
|
return self.stream.getvalue()
|
||||||
|
|
||||||
class Deserializer(object):
|
class Deserializer(object):
|
||||||
"""
|
"""
|
||||||
|
@ -17,9 +17,10 @@ class Serializer(PythonSerializer):
|
|||||||
"""
|
"""
|
||||||
def end_serialization(self):
|
def end_serialization(self):
|
||||||
simplejson.dump(self.objects, self.stream, cls=DateTimeAwareJSONEncoder, **self.options)
|
simplejson.dump(self.objects, self.stream, cls=DateTimeAwareJSONEncoder, **self.options)
|
||||||
|
|
||||||
def getvalue(self):
|
def getvalue(self):
|
||||||
return self.stream.getvalue()
|
if callable(getattr(self.stream, 'getvalue', None)):
|
||||||
|
return self.stream.getvalue()
|
||||||
|
|
||||||
def Deserializer(stream_or_string, **options):
|
def Deserializer(stream_or_string, **options):
|
||||||
"""
|
"""
|
||||||
@ -31,15 +32,15 @@ def Deserializer(stream_or_string, **options):
|
|||||||
stream = stream_or_string
|
stream = stream_or_string
|
||||||
for obj in PythonDeserializer(simplejson.load(stream)):
|
for obj in PythonDeserializer(simplejson.load(stream)):
|
||||||
yield obj
|
yield obj
|
||||||
|
|
||||||
class DateTimeAwareJSONEncoder(simplejson.JSONEncoder):
|
class DateTimeAwareJSONEncoder(simplejson.JSONEncoder):
|
||||||
"""
|
"""
|
||||||
JSONEncoder subclass that knows how to encode date/time types
|
JSONEncoder subclass that knows how to encode date/time types
|
||||||
"""
|
"""
|
||||||
|
|
||||||
DATE_FORMAT = "%Y-%m-%d"
|
DATE_FORMAT = "%Y-%m-%d"
|
||||||
TIME_FORMAT = "%H:%M:%S"
|
TIME_FORMAT = "%H:%M:%S"
|
||||||
|
|
||||||
def default(self, o):
|
def default(self, o):
|
||||||
if isinstance(o, datetime.datetime):
|
if isinstance(o, datetime.datetime):
|
||||||
return o.strftime("%s %s" % (self.DATE_FORMAT, self.TIME_FORMAT))
|
return o.strftime("%s %s" % (self.DATE_FORMAT, self.TIME_FORMAT))
|
||||||
|
@ -2,7 +2,7 @@ from django.conf import settings
|
|||||||
from django.core import signals
|
from django.core import signals
|
||||||
from django.dispatch import dispatcher
|
from django.dispatch import dispatcher
|
||||||
|
|
||||||
__all__ = ('backend', 'connection', 'DatabaseError')
|
__all__ = ('backend', 'connection', 'DatabaseError', 'IntegrityError')
|
||||||
|
|
||||||
if not settings.DATABASE_ENGINE:
|
if not settings.DATABASE_ENGINE:
|
||||||
settings.DATABASE_ENGINE = 'dummy'
|
settings.DATABASE_ENGINE = 'dummy'
|
||||||
@ -29,6 +29,7 @@ runshell = lambda: __import__('django.db.backends.%s.client' % settings.DATABASE
|
|||||||
|
|
||||||
connection = backend.DatabaseWrapper(**settings.DATABASE_OPTIONS)
|
connection = backend.DatabaseWrapper(**settings.DATABASE_OPTIONS)
|
||||||
DatabaseError = backend.DatabaseError
|
DatabaseError = backend.DatabaseError
|
||||||
|
IntegrityError = backend.IntegrityError
|
||||||
|
|
||||||
# Register an event that closes the database connection
|
# Register an event that closes the database connection
|
||||||
# when a Django request is finished.
|
# when a Django request is finished.
|
||||||
|
@ -17,6 +17,7 @@ except ImportError:
|
|||||||
mx = None
|
mx = None
|
||||||
|
|
||||||
DatabaseError = Database.DatabaseError
|
DatabaseError = Database.DatabaseError
|
||||||
|
IntegrityError = Database.IntegrityError
|
||||||
|
|
||||||
# We need to use a special Cursor class because adodbapi expects question-mark
|
# We need to use a special Cursor class because adodbapi expects question-mark
|
||||||
# param style, but Django expects "%s". This cursor converts question marks to
|
# param style, but Django expects "%s". This cursor converts question marks to
|
||||||
|
@ -15,6 +15,9 @@ def complain(*args, **kwargs):
|
|||||||
class DatabaseError(Exception):
|
class DatabaseError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class IntegrityError(DatabaseError):
|
||||||
|
pass
|
||||||
|
|
||||||
class DatabaseWrapper:
|
class DatabaseWrapper:
|
||||||
cursor = complain
|
cursor = complain
|
||||||
_commit = complain
|
_commit = complain
|
||||||
|
@ -25,6 +25,7 @@ import types
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
DatabaseError = Database.DatabaseError
|
DatabaseError = Database.DatabaseError
|
||||||
|
IntegrityError = Database.IntegrityError
|
||||||
|
|
||||||
# MySQLdb-1.2.1 supports the Python boolean type, and only uses datetime
|
# MySQLdb-1.2.1 supports the Python boolean type, and only uses datetime
|
||||||
# module for time-related columns; older versions could have used mx.DateTime
|
# module for time-related columns; older versions could have used mx.DateTime
|
||||||
|
@ -16,6 +16,7 @@ import types
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
DatabaseError = Database.DatabaseError
|
DatabaseError = Database.DatabaseError
|
||||||
|
IntegrityError = Database.IntegrityError
|
||||||
|
|
||||||
django_conversions = conversions.copy()
|
django_conversions = conversions.copy()
|
||||||
django_conversions.update({
|
django_conversions.update({
|
||||||
|
@ -12,6 +12,7 @@ except ImportError, e:
|
|||||||
raise ImproperlyConfigured, "Error loading cx_Oracle module: %s" % e
|
raise ImproperlyConfigured, "Error loading cx_Oracle module: %s" % e
|
||||||
|
|
||||||
DatabaseError = Database.Error
|
DatabaseError = Database.Error
|
||||||
|
IntegrityError = Database.IntegrityError
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Only exists in Python 2.4+
|
# Only exists in Python 2.4+
|
||||||
|
@ -14,6 +14,7 @@ except ImportError, e:
|
|||||||
raise ImproperlyConfigured, "Error loading psycopg module: %s" % e
|
raise ImproperlyConfigured, "Error loading psycopg module: %s" % e
|
||||||
|
|
||||||
DatabaseError = Database.DatabaseError
|
DatabaseError = Database.DatabaseError
|
||||||
|
IntegrityError = Database.IntegrityError
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Only exists in Python 2.4+
|
# Only exists in Python 2.4+
|
||||||
|
@ -13,6 +13,7 @@ except ImportError, e:
|
|||||||
raise ImproperlyConfigured, "Error loading psycopg2 module: %s" % e
|
raise ImproperlyConfigured, "Error loading psycopg2 module: %s" % e
|
||||||
|
|
||||||
DatabaseError = Database.DatabaseError
|
DatabaseError = Database.DatabaseError
|
||||||
|
IntegrityError = Database.IntegrityError
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Only exists in Python 2.4+
|
# Only exists in Python 2.4+
|
||||||
|
@ -18,6 +18,7 @@ except ImportError, e:
|
|||||||
raise ImproperlyConfigured, "Error loading %s module: %s" % (module, e)
|
raise ImproperlyConfigured, "Error loading %s module: %s" % (module, e)
|
||||||
|
|
||||||
DatabaseError = Database.DatabaseError
|
DatabaseError = Database.DatabaseError
|
||||||
|
IntegrityError = Database.IntegrityError
|
||||||
|
|
||||||
Database.register_converter("bool", lambda s: str(s) == '1')
|
Database.register_converter("bool", lambda s: str(s) == '1')
|
||||||
Database.register_converter("time", util.typecast_time)
|
Database.register_converter("time", util.typecast_time)
|
||||||
|
@ -260,8 +260,8 @@ class RadioSelect(Select):
|
|||||||
"Returns a RadioFieldRenderer instance rather than a Unicode string."
|
"Returns a RadioFieldRenderer instance rather than a Unicode string."
|
||||||
if value is None: value = ''
|
if value is None: value = ''
|
||||||
str_value = smart_unicode(value) # Normalize to string.
|
str_value = smart_unicode(value) # Normalize to string.
|
||||||
attrs = attrs or {}
|
final_attrs = self.build_attrs(attrs)
|
||||||
return RadioFieldRenderer(name, str_value, attrs, list(chain(self.choices, choices)))
|
return RadioFieldRenderer(name, str_value, final_attrs, list(chain(self.choices, choices)))
|
||||||
|
|
||||||
def id_for_label(self, id_):
|
def id_for_label(self, id_):
|
||||||
# RadioSelect is represented by multiple <input type="radio"> fields,
|
# RadioSelect is represented by multiple <input type="radio"> fields,
|
||||||
@ -327,14 +327,25 @@ class MultiWidget(Widget):
|
|||||||
if not isinstance(value, list):
|
if not isinstance(value, list):
|
||||||
value = self.decompress(value)
|
value = self.decompress(value)
|
||||||
output = []
|
output = []
|
||||||
|
final_attrs = self.build_attrs(attrs)
|
||||||
|
id_ = final_attrs.get('id', None)
|
||||||
for i, widget in enumerate(self.widgets):
|
for i, widget in enumerate(self.widgets):
|
||||||
try:
|
try:
|
||||||
widget_value = value[i]
|
widget_value = value[i]
|
||||||
except KeyError:
|
except IndexError:
|
||||||
widget_value = None
|
widget_value = None
|
||||||
output.append(widget.render(name + '_%s' % i, widget_value, attrs))
|
if id_:
|
||||||
|
final_attrs = dict(final_attrs, id='%s_%s' % (id_, i))
|
||||||
|
output.append(widget.render(name + '_%s' % i, widget_value, final_attrs))
|
||||||
return self.format_output(output)
|
return self.format_output(output)
|
||||||
|
|
||||||
|
def id_for_label(self, id_):
|
||||||
|
# See the comment for RadioSelect.id_for_label()
|
||||||
|
if id_:
|
||||||
|
id_ += '_0'
|
||||||
|
return id_
|
||||||
|
id_for_label = classmethod(id_for_label)
|
||||||
|
|
||||||
def value_from_datadict(self, data, name):
|
def value_from_datadict(self, data, name):
|
||||||
return [data.get(name + '_%s' % i) for i in range(len(self.widgets))]
|
return [data.get(name + '_%s' % i) for i in range(len(self.widgets))]
|
||||||
|
|
||||||
|
@ -563,7 +563,7 @@ class FilterExpression(object):
|
|||||||
filters.append( (filter_func,args))
|
filters.append( (filter_func,args))
|
||||||
upto = match.end()
|
upto = match.end()
|
||||||
if upto != len(token):
|
if upto != len(token):
|
||||||
raise TemplateSyntaxError, "Could not parse the remainder: %s" % token[upto:]
|
raise TemplateSyntaxError, "Could not parse the remainder: '%s' from '%s'" % (token[upto:], token)
|
||||||
self.var, self.filters = var, filters
|
self.var, self.filters = var, filters
|
||||||
|
|
||||||
def resolve(self, context, ignore_failures=False):
|
def resolve(self, context, ignore_failures=False):
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
from django.template import resolve_variable, Library
|
from django.template import resolve_variable, Library
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import ugettext
|
from django.utils.translation import ugettext, ungettext
|
||||||
from django.utils.encoding import smart_unicode, smart_str
|
from django.utils.encoding import smart_unicode, smart_str
|
||||||
import re
|
import re
|
||||||
import random as random_module
|
import random as random_module
|
||||||
@ -501,12 +501,12 @@ def filesizeformat(bytes):
|
|||||||
return u"0 bytes"
|
return u"0 bytes"
|
||||||
|
|
||||||
if bytes < 1024:
|
if bytes < 1024:
|
||||||
return u"%d byte%s" % (bytes, bytes != 1 and u's' or u'')
|
return ungettext("%(size)d byte", "%(size)d bytes", bytes) % {'size': bytes}
|
||||||
if bytes < 1024 * 1024:
|
if bytes < 1024 * 1024:
|
||||||
return u"%.1f KB" % (bytes / 1024)
|
return ugettext("%.1f KB") % (bytes / 1024)
|
||||||
if bytes < 1024 * 1024 * 1024:
|
if bytes < 1024 * 1024 * 1024:
|
||||||
return u"%.1f MB" % (bytes / (1024 * 1024))
|
return ugettext("%.1f MB") % (bytes / (1024 * 1024))
|
||||||
return u"%.1f GB" % (bytes / (1024 * 1024 * 1024))
|
return ugettext("%.1f GB") % (bytes / (1024 * 1024 * 1024))
|
||||||
|
|
||||||
def pluralize(value, arg=u's'):
|
def pluralize(value, arg=u's'):
|
||||||
"""
|
"""
|
||||||
|
@ -957,6 +957,7 @@ def url(parser, token):
|
|||||||
for arg in bits[2].split(','):
|
for arg in bits[2].split(','):
|
||||||
if '=' in arg:
|
if '=' in arg:
|
||||||
k, v = arg.split('=', 1)
|
k, v = arg.split('=', 1)
|
||||||
|
k = k.strip()
|
||||||
kwargs[k] = parser.compile_filter(v)
|
kwargs[k] = parser.compile_filter(v)
|
||||||
else:
|
else:
|
||||||
args.append(parser.compile_filter(arg))
|
args.append(parser.compile_filter(arg))
|
||||||
|
@ -86,7 +86,7 @@ def patch_response_headers(response, cache_timeout=None):
|
|||||||
|
|
||||||
def add_never_cache_headers(response):
|
def add_never_cache_headers(response):
|
||||||
"""
|
"""
|
||||||
Add headers to a response to indicate that
|
Add headers to a response to indicate that
|
||||||
a page should never be cached.
|
a page should never be cached.
|
||||||
"""
|
"""
|
||||||
patch_response_headers(response, cache_timeout=-1)
|
patch_response_headers(response, cache_timeout=-1)
|
||||||
|
@ -16,9 +16,9 @@ class MergeDict(object):
|
|||||||
|
|
||||||
def __contains__(self, key):
|
def __contains__(self, key):
|
||||||
return self.has_key(key)
|
return self.has_key(key)
|
||||||
|
|
||||||
def __copy__(self):
|
def __copy__(self):
|
||||||
return self.__class__(*self.dicts)
|
return self.__class__(*self.dicts)
|
||||||
|
|
||||||
def get(self, key, default=None):
|
def get(self, key, default=None):
|
||||||
try:
|
try:
|
||||||
@ -45,9 +45,9 @@ class MergeDict(object):
|
|||||||
if dict.has_key(key):
|
if dict.has_key(key):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
""" returns a copy of this object"""
|
""" returns a copy of this object"""
|
||||||
return self.__copy__()
|
return self.__copy__()
|
||||||
|
|
||||||
class SortedDict(dict):
|
class SortedDict(dict):
|
||||||
@ -99,6 +99,13 @@ class SortedDict(dict):
|
|||||||
obj.keyOrder = self.keyOrder
|
obj.keyOrder = self.keyOrder
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
"""
|
||||||
|
Replaces the normal dict.__repr__ with a version that returns the keys
|
||||||
|
in their sorted order.
|
||||||
|
"""
|
||||||
|
return '{%s}' % ', '.join(['%r: %r' % (k, v) for k, v in self.items()])
|
||||||
|
|
||||||
class MultiValueDictKeyError(KeyError):
|
class MultiValueDictKeyError(KeyError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -211,7 +218,7 @@ class MultiValueDict(dict):
|
|||||||
def update(self, *args, **kwargs):
|
def update(self, *args, **kwargs):
|
||||||
"update() extends rather than replaces existing key lists. Also accepts keyword args."
|
"update() extends rather than replaces existing key lists. Also accepts keyword args."
|
||||||
if len(args) > 1:
|
if len(args) > 1:
|
||||||
raise TypeError, "update expected at most 1 arguments, got %d", len(args)
|
raise TypeError, "update expected at most 1 arguments, got %d" % len(args)
|
||||||
if args:
|
if args:
|
||||||
other_dict = args[0]
|
other_dict = args[0]
|
||||||
if isinstance(other_dict, MultiValueDict):
|
if isinstance(other_dict, MultiValueDict):
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"""
|
"""
|
||||||
Synchronization primitives:
|
Synchronization primitives:
|
||||||
|
|
||||||
- reader-writer lock (preference to writers)
|
- reader-writer lock (preference to writers)
|
||||||
|
|
||||||
(Contributed to Django by eugene@lazutkin.com)
|
(Contributed to Django by eugene@lazutkin.com)
|
||||||
@ -14,17 +14,16 @@ except ImportError:
|
|||||||
class RWLock:
|
class RWLock:
|
||||||
"""
|
"""
|
||||||
Classic implementation of reader-writer lock with preference to writers.
|
Classic implementation of reader-writer lock with preference to writers.
|
||||||
|
|
||||||
Readers can access a resource simultaneously.
|
Readers can access a resource simultaneously.
|
||||||
Writers get an exclusive access.
|
Writers get an exclusive access.
|
||||||
|
|
||||||
API is self-descriptive:
|
API is self-descriptive:
|
||||||
reader_enters()
|
reader_enters()
|
||||||
reader_leaves()
|
reader_leaves()
|
||||||
writer_enters()
|
writer_enters()
|
||||||
writer_leaves()
|
writer_leaves()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.mutex = threading.RLock()
|
self.mutex = threading.RLock()
|
||||||
self.can_read = threading.Semaphore(0)
|
self.can_read = threading.Semaphore(0)
|
||||||
@ -33,7 +32,7 @@ class RWLock:
|
|||||||
self.active_writers = 0
|
self.active_writers = 0
|
||||||
self.waiting_readers = 0
|
self.waiting_readers = 0
|
||||||
self.waiting_writers = 0
|
self.waiting_writers = 0
|
||||||
|
|
||||||
def reader_enters(self):
|
def reader_enters(self):
|
||||||
self.mutex.acquire()
|
self.mutex.acquire()
|
||||||
try:
|
try:
|
||||||
@ -45,7 +44,7 @@ class RWLock:
|
|||||||
finally:
|
finally:
|
||||||
self.mutex.release()
|
self.mutex.release()
|
||||||
self.can_read.acquire()
|
self.can_read.acquire()
|
||||||
|
|
||||||
def reader_leaves(self):
|
def reader_leaves(self):
|
||||||
self.mutex.acquire()
|
self.mutex.acquire()
|
||||||
try:
|
try:
|
||||||
@ -56,7 +55,7 @@ class RWLock:
|
|||||||
self.can_write.release()
|
self.can_write.release()
|
||||||
finally:
|
finally:
|
||||||
self.mutex.release()
|
self.mutex.release()
|
||||||
|
|
||||||
def writer_enters(self):
|
def writer_enters(self):
|
||||||
self.mutex.acquire()
|
self.mutex.acquire()
|
||||||
try:
|
try:
|
||||||
@ -68,7 +67,7 @@ class RWLock:
|
|||||||
finally:
|
finally:
|
||||||
self.mutex.release()
|
self.mutex.release()
|
||||||
self.can_write.acquire()
|
self.can_write.acquire()
|
||||||
|
|
||||||
def writer_leaves(self):
|
def writer_leaves(self):
|
||||||
self.mutex.acquire()
|
self.mutex.acquire()
|
||||||
try:
|
try:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import datetime, math, time
|
import datetime, math, time
|
||||||
from django.utils.tzinfo import LocalTimezone
|
from django.utils.tzinfo import LocalTimezone
|
||||||
from django.utils.translation import ungettext
|
from django.utils.translation import ungettext, ugettext
|
||||||
|
|
||||||
def timesince(d, now=None):
|
def timesince(d, now=None):
|
||||||
"""
|
"""
|
||||||
@ -37,14 +37,14 @@ def timesince(d, now=None):
|
|||||||
if count != 0:
|
if count != 0:
|
||||||
break
|
break
|
||||||
if count < 0:
|
if count < 0:
|
||||||
return u'%d milliseconds' % math.floor((now - d).microseconds / 1000)
|
return ugettext('%d milliseconds') % math.floor((now - d).microseconds / 1000)
|
||||||
s = u'%d %s' % (count, name(count))
|
s = ugettext('%(number)d %(type)s') % {'number': count, 'type': name(count)}
|
||||||
if i + 1 < len(chunks):
|
if i + 1 < len(chunks):
|
||||||
# Now get the second item
|
# Now get the second item
|
||||||
seconds2, name2 = chunks[i + 1]
|
seconds2, name2 = chunks[i + 1]
|
||||||
count2 = (since - (seconds * count)) / seconds2
|
count2 = (since - (seconds * count)) / seconds2
|
||||||
if count2 != 0:
|
if count2 != 0:
|
||||||
s += ', %d %s' % (count2, name2(count2))
|
s += ugettext(', %(number)d %(type)s') % {'number': count2, 'type': name2(count2)}
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def timeuntil(d, now=None):
|
def timeuntil(d, now=None):
|
||||||
|
@ -100,14 +100,14 @@ change:
|
|||||||
|
|
||||||
.. _caching: ../cache/
|
.. _caching: ../cache/
|
||||||
.. _custom template tags and libraries: ../templates_python/
|
.. _custom template tags and libraries: ../templates_python/
|
||||||
.. _database lookup: ../db_api/
|
.. _database lookup: ../db-api/
|
||||||
.. _django-admin utility: ../django-admin/
|
.. _django-admin utility: ../django-admin/
|
||||||
.. _fastcgi integration: ../fastcgi/
|
.. _fastcgi integration: ../fastcgi/
|
||||||
.. _flatpages: ../flatpages/
|
.. _flatpages: ../flatpages/
|
||||||
.. _generic views: ../generic_views/
|
.. _generic views: ../generic_views/
|
||||||
.. _internationalization: ../i18n/
|
.. _internationalization: ../i18n/
|
||||||
.. _legacy database integration: ../legacy_databases/
|
.. _legacy database integration: ../legacy_databases/
|
||||||
.. _model definition: ../model_api/
|
.. _model definition: ../model-api/
|
||||||
.. _mod_python integration: ../modpython/
|
.. _mod_python integration: ../modpython/
|
||||||
.. _redirects: ../redirects/
|
.. _redirects: ../redirects/
|
||||||
.. _request/response objects: ../request_response/
|
.. _request/response objects: ../request_response/
|
||||||
|
@ -144,7 +144,7 @@ custom methods:
|
|||||||
Raises ``django.contrib.auth.models.SiteProfileNotAvailable`` if the current site
|
Raises ``django.contrib.auth.models.SiteProfileNotAvailable`` if the current site
|
||||||
doesn't allow profiles.
|
doesn't allow profiles.
|
||||||
|
|
||||||
.. _Django model: ../model_api/
|
.. _Django model: ../model-api/
|
||||||
.. _DEFAULT_FROM_EMAIL: ../settings/#default-from-email
|
.. _DEFAULT_FROM_EMAIL: ../settings/#default-from-email
|
||||||
|
|
||||||
Manager functions
|
Manager functions
|
||||||
@ -204,9 +204,11 @@ The ``password`` attribute of a ``User`` object is a string in this format::
|
|||||||
|
|
||||||
That's hashtype, salt and hash, separated by the dollar-sign character.
|
That's hashtype, salt and hash, separated by the dollar-sign character.
|
||||||
|
|
||||||
Hashtype is either ``sha1`` (default) or ``md5`` -- the algorithm used to
|
Hashtype is either ``sha1`` (default), ``md5`` or ``crypt`` -- the algorithm
|
||||||
perform a one-way hash of the password. Salt is a random string used to salt
|
used to perform a one-way hash of the password. Salt is a random string used
|
||||||
the raw password to create the hash.
|
to salt the raw password to create the hash. Note that the ``crypt`` method is
|
||||||
|
only supported on platforms that have the standard Python ``crypt`` module
|
||||||
|
available.
|
||||||
|
|
||||||
For example::
|
For example::
|
||||||
|
|
||||||
@ -387,14 +389,15 @@ introduced in Python 2.4::
|
|||||||
|
|
||||||
``login_required`` does the following:
|
``login_required`` does the following:
|
||||||
|
|
||||||
* If the user isn't logged in, redirect to ``/accounts/login/``, passing
|
* If the user isn't logged in, redirect to ``settings.LOGIN_URL``
|
||||||
the current absolute URL in the query string as ``next``. For example:
|
(``/accounts/login/`` by default), passing the current absolute URL
|
||||||
|
in the query string as ``next``. For example:
|
||||||
``/accounts/login/?next=/polls/3/``.
|
``/accounts/login/?next=/polls/3/``.
|
||||||
* If the user is logged in, execute the view normally. The view code is
|
* If the user is logged in, execute the view normally. The view code is
|
||||||
free to assume the user is logged in.
|
free to assume the user is logged in.
|
||||||
|
|
||||||
Note that you'll need to map the appropriate Django view to ``/accounts/login/``.
|
Note that you'll need to map the appropriate Django view to ``settings.LOGIN_URL``.
|
||||||
To do this, add the following line to your URLconf::
|
For example, using the defaults, add the following line to your URLconf::
|
||||||
|
|
||||||
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
|
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
|
||||||
|
|
||||||
@ -405,9 +408,9 @@ Here's what ``django.contrib.auth.views.login`` does:
|
|||||||
|
|
||||||
* If called via ``POST``, it tries to log the user in. If login is
|
* If called via ``POST``, it tries to log the user in. If login is
|
||||||
successful, the view redirects to the URL specified in ``next``. If
|
successful, the view redirects to the URL specified in ``next``. If
|
||||||
``next`` isn't provided, it redirects to ``/accounts/profile/`` (which is
|
``next`` isn't provided, it redirects to ``settings.LOGIN_REDIRECT_URL``
|
||||||
currently hard-coded). If login isn't successful, it redisplays the login
|
(which defaults to ``/accounts/profile/``). If login isn't successful,
|
||||||
form.
|
it redisplays the login form.
|
||||||
|
|
||||||
It's your responsibility to provide the login form in a template called
|
It's your responsibility to provide the login form in a template called
|
||||||
``registration/login.html`` by default. This template gets passed three
|
``registration/login.html`` by default. This template gets passed three
|
||||||
@ -487,7 +490,7 @@ Logs a user out, then redirects to the login page.
|
|||||||
**Optional arguments:**
|
**Optional arguments:**
|
||||||
|
|
||||||
* ``login_url``: The URL of the login page to redirect to. This
|
* ``login_url``: The URL of the login page to redirect to. This
|
||||||
will default to ``/accounts/login/`` if not supplied.
|
will default to ``settings.LOGIN_URL`` if not supplied.
|
||||||
|
|
||||||
``django.contrib.auth.views.password_change``
|
``django.contrib.auth.views.password_change``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -569,7 +572,7 @@ successful login.
|
|||||||
**Optional arguments:**
|
**Optional arguments:**
|
||||||
|
|
||||||
* ``login_url``: The URL of the login page to redirect to. This
|
* ``login_url``: The URL of the login page to redirect to. This
|
||||||
will default to ``/accounts/login/`` if not supplied.
|
will default to ``settings.LOGIN_URL`` if not supplied.
|
||||||
|
|
||||||
Built-in manipulators
|
Built-in manipulators
|
||||||
---------------------
|
---------------------
|
||||||
@ -636,7 +639,7 @@ Note that ``user_passes_test`` does not automatically check that the ``User``
|
|||||||
is not anonymous.
|
is not anonymous.
|
||||||
|
|
||||||
``user_passes_test()`` takes an optional ``login_url`` argument, which lets you
|
``user_passes_test()`` takes an optional ``login_url`` argument, which lets you
|
||||||
specify the URL for your login page (``/accounts/login/`` by default).
|
specify the URL for your login page (``settings.LOGIN_URL`` by default).
|
||||||
|
|
||||||
Example in Python 2.3 syntax::
|
Example in Python 2.3 syntax::
|
||||||
|
|
||||||
@ -680,7 +683,7 @@ parameter. Example::
|
|||||||
my_view = permission_required('polls.can_vote', login_url='/loginpage/')(my_view)
|
my_view = permission_required('polls.can_vote', login_url='/loginpage/')(my_view)
|
||||||
|
|
||||||
As in the ``login_required`` decorator, ``login_url`` defaults to
|
As in the ``login_required`` decorator, ``login_url`` defaults to
|
||||||
``'/accounts/login/'``.
|
``settings.LOGIN_URL``.
|
||||||
|
|
||||||
Limiting access to generic views
|
Limiting access to generic views
|
||||||
--------------------------------
|
--------------------------------
|
||||||
@ -757,7 +760,7 @@ This example model creates three custom permissions::
|
|||||||
The only thing this does is create those extra permissions when you run
|
The only thing this does is create those extra permissions when you run
|
||||||
``syncdb``.
|
``syncdb``.
|
||||||
|
|
||||||
.. _model Meta attribute: ../model_api/#meta-options
|
.. _model Meta attribute: ../model-api/#meta-options
|
||||||
|
|
||||||
API reference
|
API reference
|
||||||
-------------
|
-------------
|
||||||
|
@ -6,7 +6,7 @@ Once you've created your `data models`_, Django automatically gives you a
|
|||||||
database-abstraction API that lets you create, retrieve, update and delete
|
database-abstraction API that lets you create, retrieve, update and delete
|
||||||
objects. This document explains that API.
|
objects. This document explains that API.
|
||||||
|
|
||||||
.. _`data models`: ../model_api/
|
.. _`data models`: ../model-api/
|
||||||
|
|
||||||
Throughout this reference, we'll refer to the following models, which comprise
|
Throughout this reference, we'll refer to the following models, which comprise
|
||||||
a weblog application::
|
a weblog application::
|
||||||
@ -85,7 +85,7 @@ There's no way to tell what the value of an ID will be before you call
|
|||||||
unless you explicitly specify ``primary_key=True`` on a field. See the
|
unless you explicitly specify ``primary_key=True`` on a field. See the
|
||||||
`AutoField documentation`_.)
|
`AutoField documentation`_.)
|
||||||
|
|
||||||
.. _AutoField documentation: ../model_api/#autofield
|
.. _AutoField documentation: ../model-api/#autofield
|
||||||
|
|
||||||
Explicitly specifying auto-primary-key values
|
Explicitly specifying auto-primary-key values
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -1801,4 +1801,4 @@ interface to your database. You can access your database via other tools,
|
|||||||
programming languages or database frameworks; there's nothing Django-specific
|
programming languages or database frameworks; there's nothing Django-specific
|
||||||
about your database.
|
about your database.
|
||||||
|
|
||||||
.. _Executing custom SQL: ../model_api/#executing-custom-sql
|
.. _Executing custom SQL: ../model-api/#executing-custom-sql
|
||||||
|
@ -512,7 +512,7 @@ type, create an initial data file and put something like this in it::
|
|||||||
As explained in the `SQL initial data file`_ documentation, this SQL file can
|
As explained in the `SQL initial data file`_ documentation, this SQL file can
|
||||||
contain arbitrary SQL, so you can make any sorts of changes you need to make.
|
contain arbitrary SQL, so you can make any sorts of changes you need to make.
|
||||||
|
|
||||||
.. _SQL initial data file: ../model_api/#providing-initial-sql-data
|
.. _SQL initial data file: ../model-api/#providing-initial-sql-data
|
||||||
|
|
||||||
Why is Django leaking memory?
|
Why is Django leaking memory?
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
@ -84,9 +84,9 @@ Flatpages are represented by a standard `Django model`_, which lives in
|
|||||||
`django/contrib/flatpages/models.py`_. You can access flatpage objects via the
|
`django/contrib/flatpages/models.py`_. You can access flatpage objects via the
|
||||||
`Django database API`_.
|
`Django database API`_.
|
||||||
|
|
||||||
.. _Django model: ../model_api/
|
.. _Django model: ../model-api/
|
||||||
.. _django/contrib/flatpages/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/flatpages/models.py
|
.. _django/contrib/flatpages/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/flatpages/models.py
|
||||||
.. _Django database API: ../db_api/
|
.. _Django database API: ../db-api/
|
||||||
|
|
||||||
Flatpage templates
|
Flatpage templates
|
||||||
==================
|
==================
|
||||||
|
@ -691,5 +691,5 @@ fails. If no message is passed in, a default message is used.
|
|||||||
document for more details).
|
document for more details).
|
||||||
|
|
||||||
.. _`generic views`: ../generic_views/
|
.. _`generic views`: ../generic_views/
|
||||||
.. _`models API`: ../model_api/
|
.. _`models API`: ../model-api/
|
||||||
.. _settings: ../settings/
|
.. _settings: ../settings/
|
||||||
|
@ -71,7 +71,7 @@ are first evaluated, so if you want to pass in a QuerySet via
|
|||||||
``extra_context`` that is always fresh you need to wrap it in a function or
|
``extra_context`` that is always fresh you need to wrap it in a function or
|
||||||
lambda that returns the QuerySet.
|
lambda that returns the QuerySet.
|
||||||
|
|
||||||
.. _database API docs: ../db_api/
|
.. _database API docs: ../db-api/
|
||||||
|
|
||||||
"Simple" generic views
|
"Simple" generic views
|
||||||
======================
|
======================
|
||||||
|
@ -175,7 +175,7 @@ class, though::
|
|||||||
verbose_name = _('my thing')
|
verbose_name = _('my thing')
|
||||||
verbose_name_plural = _('mythings')
|
verbose_name_plural = _('mythings')
|
||||||
|
|
||||||
.. _Django models: ../model_api/
|
.. _Django models: ../model-api/
|
||||||
|
|
||||||
Pluralization
|
Pluralization
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
@ -194,14 +194,23 @@ This doesn't accept ``maxlength``; its ``maxlength`` is automatically set to
|
|||||||
``FileField``
|
``FileField``
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
A file-upload field.
|
A file-upload field. Has one **required** argument:
|
||||||
|
|
||||||
Has an extra required argument, ``upload_to``, a local filesystem path to
|
====================== ===================================================
|
||||||
which files should be upload. This path may contain `strftime formatting`_,
|
Argument Description
|
||||||
which will be replaced by the date/time of the file upload (so that
|
====================== ===================================================
|
||||||
uploaded files don't fill up the given directory).
|
``upload_to`` A local filesystem path that will be appended to
|
||||||
|
your ``MEDIA_ROOT`` setting to determine the
|
||||||
|
output of the ``get_<fieldname>_url()`` helper
|
||||||
|
function.
|
||||||
|
====================== ===================================================
|
||||||
|
|
||||||
The admin represents this as an ``<input type="file">`` (a file-upload widget).
|
This path may contain `strftime formatting`_, which will be replaced by the
|
||||||
|
date/time of the file upload (so that uploaded files don't fill up the given
|
||||||
|
directory).
|
||||||
|
|
||||||
|
The admin represents this field as an ``<input type="file">`` (a file-upload
|
||||||
|
widget).
|
||||||
|
|
||||||
Using a ``FileField`` or an ``ImageField`` (see below) in a model takes a few
|
Using a ``FileField`` or an ``ImageField`` (see below) in a model takes a few
|
||||||
steps:
|
steps:
|
||||||
@ -246,7 +255,7 @@ visiting its URL on your site. Don't allow that.
|
|||||||
|
|
||||||
A field whose choices are limited to the filenames in a certain directory
|
A field whose choices are limited to the filenames in a certain directory
|
||||||
on the filesystem. Has three special arguments, of which the first is
|
on the filesystem. Has three special arguments, of which the first is
|
||||||
required:
|
**required**:
|
||||||
|
|
||||||
====================== ===================================================
|
====================== ===================================================
|
||||||
Argument Description
|
Argument Description
|
||||||
|
@ -66,6 +66,6 @@ Redirects are represented by a standard `Django model`_, which lives in
|
|||||||
`django/contrib/redirects/models.py`_. You can access redirect
|
`django/contrib/redirects/models.py`_. You can access redirect
|
||||||
objects via the `Django database API`_.
|
objects via the `Django database API`_.
|
||||||
|
|
||||||
.. _Django model: ../model_api/
|
.. _Django model: ../model-api/
|
||||||
.. _django/contrib/redirects/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/redirects/models.py
|
.. _django/contrib/redirects/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/redirects/models.py
|
||||||
.. _Django database API: ../db_api/
|
.. _Django database API: ../db-api/
|
||||||
|
@ -93,6 +93,7 @@ All attributes except ``session`` should be considered read-only.
|
|||||||
* ``CONTENT_TYPE``
|
* ``CONTENT_TYPE``
|
||||||
* ``HTTP_ACCEPT_ENCODING``
|
* ``HTTP_ACCEPT_ENCODING``
|
||||||
* ``HTTP_ACCEPT_LANGUAGE``
|
* ``HTTP_ACCEPT_LANGUAGE``
|
||||||
|
* ``HTTP_HOST`` -- The HTTP Host header sent by the client.
|
||||||
* ``HTTP_REFERER`` -- The referring page, if any.
|
* ``HTTP_REFERER`` -- The referring page, if any.
|
||||||
* ``HTTP_USER_AGENT`` -- The client's user-agent string.
|
* ``HTTP_USER_AGENT`` -- The client's user-agent string.
|
||||||
* ``QUERY_STRING`` -- The query string, as a single (unparsed) string.
|
* ``QUERY_STRING`` -- The query string, as a single (unparsed) string.
|
||||||
|
@ -27,7 +27,7 @@ data to (see `Serialization formats`_) and a QuerySet_ to serialize.
|
|||||||
(Actually, the second argument can be any iterator that yields Django objects,
|
(Actually, the second argument can be any iterator that yields Django objects,
|
||||||
but it'll almost always be a QuerySet).
|
but it'll almost always be a QuerySet).
|
||||||
|
|
||||||
.. _QuerySet: ../db_api/#retrieving-objects
|
.. _QuerySet: ../db-api/#retrieving-objects
|
||||||
|
|
||||||
You can also use a serializer object directly::
|
You can also use a serializer object directly::
|
||||||
|
|
||||||
|
@ -570,6 +570,21 @@ strings for translation, but the translation won't happen at runtime -- so
|
|||||||
you'll have to remember to wrap the languages in the *real* ``gettext()`` in
|
you'll have to remember to wrap the languages in the *real* ``gettext()`` in
|
||||||
any code that uses ``LANGUAGES`` at runtime.
|
any code that uses ``LANGUAGES`` at runtime.
|
||||||
|
|
||||||
|
LOGIN_URL
|
||||||
|
---------
|
||||||
|
|
||||||
|
Default: ``'/accounts/login/'``
|
||||||
|
|
||||||
|
The URL where requests are redirected for login, specially when using the
|
||||||
|
`@login_required`_ decorator.
|
||||||
|
|
||||||
|
LOGOUT_URL
|
||||||
|
----------
|
||||||
|
|
||||||
|
Default: ``'/accounts/logout/'``
|
||||||
|
|
||||||
|
LOGIN_URL counterpart.
|
||||||
|
|
||||||
MANAGERS
|
MANAGERS
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@ -628,6 +643,16 @@ locales have different formats. For example, U.S. English would say
|
|||||||
See `allowed date format strings`_. See also DATE_FORMAT, DATETIME_FORMAT,
|
See `allowed date format strings`_. See also DATE_FORMAT, DATETIME_FORMAT,
|
||||||
TIME_FORMAT and YEAR_MONTH_FORMAT.
|
TIME_FORMAT and YEAR_MONTH_FORMAT.
|
||||||
|
|
||||||
|
LOGIN_REDIRECT_URL
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Default: ``'/accounts/profile/'``
|
||||||
|
|
||||||
|
The URL where requests are redirected after login when the
|
||||||
|
``contrib.auth.login`` view gets no ``next`` parameter.
|
||||||
|
|
||||||
|
This is used by the `@login_required`_ decorator, for example.
|
||||||
|
|
||||||
PREPEND_WWW
|
PREPEND_WWW
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
@ -882,7 +907,7 @@ Default: ``Django/<version> (http://www.djangoproject.com/)``
|
|||||||
The string to use as the ``User-Agent`` header when checking to see if URLs
|
The string to use as the ``User-Agent`` header when checking to see if URLs
|
||||||
exist (see the ``verify_exists`` option on URLField_).
|
exist (see the ``verify_exists`` option on URLField_).
|
||||||
|
|
||||||
.. _URLField: ../model_api/#urlfield
|
.. _URLField: ../model-api/#urlfield
|
||||||
|
|
||||||
USE_ETAGS
|
USE_ETAGS
|
||||||
---------
|
---------
|
||||||
@ -1020,6 +1045,8 @@ Also, it's an error to call ``configure()`` more than once, or to call
|
|||||||
It boils down to this: Use exactly one of either ``configure()`` or
|
It boils down to this: Use exactly one of either ``configure()`` or
|
||||||
``DJANGO_SETTINGS_MODULE``. Not both, and not neither.
|
``DJANGO_SETTINGS_MODULE``. Not both, and not neither.
|
||||||
|
|
||||||
|
.. _@login_required: ../authentication/#the-login-required-decorator
|
||||||
|
|
||||||
Error reporting via e-mail
|
Error reporting via e-mail
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
@ -276,8 +276,8 @@ you want your admin site to have access to all objects (not just site-specific
|
|||||||
ones), put ``objects = models.Manager()`` in your model, before you define
|
ones), put ``objects = models.Manager()`` in your model, before you define
|
||||||
``CurrentSiteManager``.
|
``CurrentSiteManager``.
|
||||||
|
|
||||||
.. _manager: ../model_api/#managers
|
.. _manager: ../model-api/#managers
|
||||||
.. _manager documentation: ../model_api/#managers
|
.. _manager documentation: ../model-api/#managers
|
||||||
|
|
||||||
How Django uses the sites framework
|
How Django uses the sites framework
|
||||||
===================================
|
===================================
|
||||||
|
@ -159,7 +159,7 @@ put into those elements.
|
|||||||
{{ obj.description }}
|
{{ obj.description }}
|
||||||
|
|
||||||
.. _chicagocrime.org: http://www.chicagocrime.org/
|
.. _chicagocrime.org: http://www.chicagocrime.org/
|
||||||
.. _object-relational mapper: ../db_api/
|
.. _object-relational mapper: ../db-api/
|
||||||
.. _Django templates: ../templates/
|
.. _Django templates: ../templates/
|
||||||
|
|
||||||
A complex example
|
A complex example
|
||||||
|
@ -577,5 +577,5 @@ For full details on the database API, see our `Database API reference`_.
|
|||||||
When you're comfortable with the API, read `part 2 of this tutorial`_ to get
|
When you're comfortable with the API, read `part 2 of this tutorial`_ to get
|
||||||
Django's automatic admin working.
|
Django's automatic admin working.
|
||||||
|
|
||||||
.. _Database API reference: ../db_api/
|
.. _Database API reference: ../db-api/
|
||||||
.. _part 2 of this tutorial: ../tutorial02/
|
.. _part 2 of this tutorial: ../tutorial02/
|
||||||
|
@ -219,7 +219,7 @@ template. Note that we use ``dict()`` to return an altered dictionary in place.
|
|||||||
If you'd like to know more about how that works, The Django database API
|
If you'd like to know more about how that works, The Django database API
|
||||||
documentation `explains the lazy nature of QuerySet objects`_.
|
documentation `explains the lazy nature of QuerySet objects`_.
|
||||||
|
|
||||||
.. _explains the lazy nature of QuerySet objects: ../db_api/#querysets-are-lazy
|
.. _explains the lazy nature of QuerySet objects: ../db-api/#querysets-are-lazy
|
||||||
|
|
||||||
In previous parts of the tutorial, the templates have been provided with a context
|
In previous parts of the tutorial, the templates have been provided with a context
|
||||||
that contains the ``poll`` and ``latest_poll_list`` context variables. However,
|
that contains the ``poll`` and ``latest_poll_list`` context variables. However,
|
||||||
|
@ -52,6 +52,8 @@
|
|||||||
'not one'
|
'not one'
|
||||||
>>> d.keys() == d.copy().keys()
|
>>> d.keys() == d.copy().keys()
|
||||||
True
|
True
|
||||||
|
>>> print repr(d)
|
||||||
|
{'one': 'not one', 'two': 'two', 'three': 'three'}
|
||||||
|
|
||||||
### DotExpandedDict ############################################################
|
### DotExpandedDict ############################################################
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -658,10 +658,31 @@ Traceback (most recent call last):
|
|||||||
...
|
...
|
||||||
IndexError: list index out of range
|
IndexError: list index out of range
|
||||||
|
|
||||||
|
# Unicode choices are correctly rendered as HTML
|
||||||
>>> w = RadioSelect()
|
>>> w = RadioSelect()
|
||||||
>>> unicode(w.render('email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]))
|
>>> unicode(w.render('email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]))
|
||||||
u'<ul>\n<li><label><input checked="checked" type="radio" name="email" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /> \u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</label></li>\n<li><label><input type="radio" name="email" value="\u0107\u017e\u0161\u0111" /> abc\u0107\u017e\u0161\u0111</label></li>\n</ul>'
|
u'<ul>\n<li><label><input checked="checked" type="radio" name="email" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /> \u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</label></li>\n<li><label><input type="radio" name="email" value="\u0107\u017e\u0161\u0111" /> abc\u0107\u017e\u0161\u0111</label></li>\n</ul>'
|
||||||
|
|
||||||
|
# Attributes provided at instantiation are passed to the constituent inputs
|
||||||
|
>>> w = RadioSelect(attrs={'id':'foo'})
|
||||||
|
>>> print w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
|
||||||
|
<ul>
|
||||||
|
<li><label><input checked="checked" type="radio" id="foo_0" value="J" name="beatle" /> John</label></li>
|
||||||
|
<li><label><input type="radio" id="foo_1" value="P" name="beatle" /> Paul</label></li>
|
||||||
|
<li><label><input type="radio" id="foo_2" value="G" name="beatle" /> George</label></li>
|
||||||
|
<li><label><input type="radio" id="foo_3" value="R" name="beatle" /> Ringo</label></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
# Attributes provided at render-time are passed to the constituent inputs
|
||||||
|
>>> w = RadioSelect()
|
||||||
|
>>> print w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')), attrs={'id':'bar'})
|
||||||
|
<ul>
|
||||||
|
<li><label><input checked="checked" type="radio" id="bar_0" value="J" name="beatle" /> John</label></li>
|
||||||
|
<li><label><input type="radio" id="bar_1" value="P" name="beatle" /> Paul</label></li>
|
||||||
|
<li><label><input type="radio" id="bar_2" value="G" name="beatle" /> George</label></li>
|
||||||
|
<li><label><input type="radio" id="bar_3" value="R" name="beatle" /> Ringo</label></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
# CheckboxSelectMultiple Widget ###############################################
|
# CheckboxSelectMultiple Widget ###############################################
|
||||||
|
|
||||||
>>> w = CheckboxSelectMultiple()
|
>>> w = CheckboxSelectMultiple()
|
||||||
@ -783,6 +804,11 @@ u'<ul>\n<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li
|
|||||||
u'<input type="text" class="big" value="john" name="name_0" /><br /><input type="text" class="small" value="lennon" name="name_1" />'
|
u'<input type="text" class="big" value="john" name="name_0" /><br /><input type="text" class="small" value="lennon" name="name_1" />'
|
||||||
>>> w.render('name', 'john__lennon')
|
>>> w.render('name', 'john__lennon')
|
||||||
u'<input type="text" class="big" value="john" name="name_0" /><br /><input type="text" class="small" value="lennon" name="name_1" />'
|
u'<input type="text" class="big" value="john" name="name_0" /><br /><input type="text" class="small" value="lennon" name="name_1" />'
|
||||||
|
>>> w.render('name', 'john__lennon', attrs={'id':'foo'})
|
||||||
|
u'<input id="foo_0" type="text" class="big" value="john" name="name_0" /><br /><input id="foo_1" type="text" class="small" value="lennon" name="name_1" />'
|
||||||
|
>>> w = MyMultiWidget(widgets=(TextInput(attrs={'class': 'big'}), TextInput(attrs={'class': 'small'})), attrs={'id': 'bar'})
|
||||||
|
>>> w.render('name', ['john', 'lennon'])
|
||||||
|
u'<input id="bar_0" type="text" class="big" value="john" name="name_0" /><br /><input id="bar_1" type="text" class="small" value="lennon" name="name_1" />'
|
||||||
|
|
||||||
# SplitDateTimeWidget #########################################################
|
# SplitDateTimeWidget #########################################################
|
||||||
|
|
||||||
|
@ -700,7 +700,7 @@ class Templates(unittest.TestCase):
|
|||||||
### URL TAG ########################################################
|
### URL TAG ########################################################
|
||||||
# Successes
|
# Successes
|
||||||
'url01' : ('{% url regressiontests.templates.views.client client.id %}', {'client': {'id': 1}}, '/url_tag/client/1/'),
|
'url01' : ('{% url regressiontests.templates.views.client client.id %}', {'client': {'id': 1}}, '/url_tag/client/1/'),
|
||||||
'url02' : ('{% url regressiontests.templates.views.client_action client.id,action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),
|
'url02' : ('{% url regressiontests.templates.views.client_action client.id, action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),
|
||||||
'url03' : ('{% url regressiontests.templates.views.index %}', {}, '/url_tag/'),
|
'url03' : ('{% url regressiontests.templates.views.index %}', {}, '/url_tag/'),
|
||||||
'url04' : ('{% url named-client client.id %}', {'client': {'id': 1}}, '/url_tag/named-client/1/'),
|
'url04' : ('{% url named-client client.id %}', {'client': {'id': 1}}, '/url_tag/named-client/1/'),
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user