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
|
||||
David Ascher <http://ascher.ca/>
|
||||
Arthur <avandorp@gmail.com>
|
||||
axiak@mit.edu
|
||||
Jiri Barton
|
||||
Ned Batchelder <http://www.nedbatchelder.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/>
|
||||
Andy Dustman <farcepest@gmail.com>
|
||||
Clint Ecker
|
||||
enlight
|
||||
Enrico <rico.bl@gmail.com>
|
||||
Ludvig Ericson <ludvig.ericson@gmail.com>
|
||||
Dirk Eschler <dirk.eschler@gmx.net>
|
||||
@ -108,6 +110,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
hipertracker@gmail.com
|
||||
Ian Holsman <http://feh.holsman.net/>
|
||||
Kieran Holland <http://www.kieranholland.com>
|
||||
Sung-Jin Hong <serialx.net@gmail.com>
|
||||
Robert Rock Howard <http://djangomojo.com/>
|
||||
Jason Huggins <http://www.jrandolph.com/blog/>
|
||||
Hyun Mi Ae
|
||||
|
@ -315,6 +315,12 @@ BANNED_IPS = ()
|
||||
|
||||
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
|
||||
|
||||
LOGIN_URL = '/accounts/login/'
|
||||
|
||||
LOGOUT_URL = '/accounts/logout/'
|
||||
|
||||
LOGIN_REDIRECT_URL = '/accounts/profile/'
|
||||
|
||||
###########
|
||||
# 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:
|
||||
login(request, user)
|
||||
# TODO: set last_login with an event.
|
||||
user.last_login = datetime.datetime.now()
|
||||
user.save()
|
||||
if request.POST.has_key('post_data'):
|
||||
post_data = _decode_post_data(request.POST['post_data'])
|
||||
if post_data and not post_data.has_key(LOGIN_FORM_KEY):
|
||||
|
@ -1,8 +1,8 @@
|
||||
import datetime
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
||||
SESSION_KEY = '_auth_user_id'
|
||||
BACKEND_SESSION_KEY = '_auth_user_backend'
|
||||
LOGIN_URL = '/accounts/login/'
|
||||
REDIRECT_FIELD_NAME = 'next'
|
||||
|
||||
def load_backend(path):
|
||||
@ -49,6 +49,8 @@ def login(request, user):
|
||||
if user is None:
|
||||
user = request.user
|
||||
# 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[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 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,
|
||||
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.
|
||||
"""
|
||||
if not login_url:
|
||||
from django.conf import settings
|
||||
login_url = settings.LOGIN_URL
|
||||
def _dec(view_func):
|
||||
def _checklogin(request, *args, **kwargs):
|
||||
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
|
||||
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.db import backend, connection, models
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.translation import ugettext_lazy
|
||||
import datetime
|
||||
|
||||
def check_password(raw_password, enc_password):
|
||||
@ -17,6 +17,12 @@ def check_password(raw_password, enc_password):
|
||||
elif algo == 'sha1':
|
||||
import sha
|
||||
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."
|
||||
|
||||
class SiteProfileNotAvailable(Exception):
|
||||
@ -273,7 +279,7 @@ class AnonymousUser(object):
|
||||
pass
|
||||
|
||||
def __unicode__(self):
|
||||
return u'AnonymousUser'
|
||||
return ugettext_lazy('AnonymousUser')
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, self.__class__)
|
||||
|
@ -6,7 +6,7 @@ from django.template import RequestContext
|
||||
from django.contrib.sites.models import Site
|
||||
from django.http import HttpResponseRedirect
|
||||
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'):
|
||||
"Displays the login form and handles the login action."
|
||||
@ -17,7 +17,8 @@ def login(request, template_name='registration/login.html'):
|
||||
if not errors:
|
||||
# Light security check -- make sure redirect_to isn't garbage.
|
||||
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
|
||||
login(request, manipulator.get_user())
|
||||
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.
|
||||
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."
|
||||
if not login_url:
|
||||
from django.conf import settings
|
||||
login_url = settings.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"
|
||||
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))
|
||||
|
||||
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">
|
||||
|
||||
{% 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 %}
|
||||
<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 %}
|
||||
|
@ -25,6 +25,7 @@ class CommentFormNode(template.Node):
|
||||
self.is_public = is_public
|
||||
|
||||
def render(self, context):
|
||||
from django.conf import settings
|
||||
from django.utils.text import normalize_newlines
|
||||
import base64
|
||||
context.push()
|
||||
@ -64,6 +65,7 @@ class CommentFormNode(template.Node):
|
||||
if 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['logout_url'] = settings.LOGOUT_URL
|
||||
default_form = loader.get_template(COMMENT_FORM)
|
||||
output = default_form.render(context)
|
||||
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):
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
|
@ -19,7 +19,8 @@ class Serializer(PythonSerializer):
|
||||
simplejson.dump(self.objects, self.stream, cls=DateTimeAwareJSONEncoder, **self.options)
|
||||
|
||||
def getvalue(self):
|
||||
return self.stream.getvalue()
|
||||
if callable(getattr(self.stream, 'getvalue', None)):
|
||||
return self.stream.getvalue()
|
||||
|
||||
def Deserializer(stream_or_string, **options):
|
||||
"""
|
||||
|
@ -2,7 +2,7 @@ from django.conf import settings
|
||||
from django.core import signals
|
||||
from django.dispatch import dispatcher
|
||||
|
||||
__all__ = ('backend', 'connection', 'DatabaseError')
|
||||
__all__ = ('backend', 'connection', 'DatabaseError', 'IntegrityError')
|
||||
|
||||
if not settings.DATABASE_ENGINE:
|
||||
settings.DATABASE_ENGINE = 'dummy'
|
||||
@ -29,6 +29,7 @@ runshell = lambda: __import__('django.db.backends.%s.client' % settings.DATABASE
|
||||
|
||||
connection = backend.DatabaseWrapper(**settings.DATABASE_OPTIONS)
|
||||
DatabaseError = backend.DatabaseError
|
||||
IntegrityError = backend.IntegrityError
|
||||
|
||||
# Register an event that closes the database connection
|
||||
# when a Django request is finished.
|
||||
|
@ -17,6 +17,7 @@ except ImportError:
|
||||
mx = None
|
||||
|
||||
DatabaseError = Database.DatabaseError
|
||||
IntegrityError = Database.IntegrityError
|
||||
|
||||
# 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
|
||||
|
@ -15,6 +15,9 @@ def complain(*args, **kwargs):
|
||||
class DatabaseError(Exception):
|
||||
pass
|
||||
|
||||
class IntegrityError(DatabaseError):
|
||||
pass
|
||||
|
||||
class DatabaseWrapper:
|
||||
cursor = complain
|
||||
_commit = complain
|
||||
|
@ -25,6 +25,7 @@ import types
|
||||
import re
|
||||
|
||||
DatabaseError = Database.DatabaseError
|
||||
IntegrityError = Database.IntegrityError
|
||||
|
||||
# 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
|
||||
|
@ -16,6 +16,7 @@ import types
|
||||
import re
|
||||
|
||||
DatabaseError = Database.DatabaseError
|
||||
IntegrityError = Database.IntegrityError
|
||||
|
||||
django_conversions = conversions.copy()
|
||||
django_conversions.update({
|
||||
|
@ -12,6 +12,7 @@ except ImportError, e:
|
||||
raise ImproperlyConfigured, "Error loading cx_Oracle module: %s" % e
|
||||
|
||||
DatabaseError = Database.Error
|
||||
IntegrityError = Database.IntegrityError
|
||||
|
||||
try:
|
||||
# Only exists in Python 2.4+
|
||||
|
@ -14,6 +14,7 @@ except ImportError, e:
|
||||
raise ImproperlyConfigured, "Error loading psycopg module: %s" % e
|
||||
|
||||
DatabaseError = Database.DatabaseError
|
||||
IntegrityError = Database.IntegrityError
|
||||
|
||||
try:
|
||||
# Only exists in Python 2.4+
|
||||
|
@ -13,6 +13,7 @@ except ImportError, e:
|
||||
raise ImproperlyConfigured, "Error loading psycopg2 module: %s" % e
|
||||
|
||||
DatabaseError = Database.DatabaseError
|
||||
IntegrityError = Database.IntegrityError
|
||||
|
||||
try:
|
||||
# Only exists in Python 2.4+
|
||||
|
@ -18,6 +18,7 @@ except ImportError, e:
|
||||
raise ImproperlyConfigured, "Error loading %s module: %s" % (module, e)
|
||||
|
||||
DatabaseError = Database.DatabaseError
|
||||
IntegrityError = Database.IntegrityError
|
||||
|
||||
Database.register_converter("bool", lambda s: str(s) == '1')
|
||||
Database.register_converter("time", util.typecast_time)
|
||||
|
@ -260,8 +260,8 @@ class RadioSelect(Select):
|
||||
"Returns a RadioFieldRenderer instance rather than a Unicode string."
|
||||
if value is None: value = ''
|
||||
str_value = smart_unicode(value) # Normalize to string.
|
||||
attrs = attrs or {}
|
||||
return RadioFieldRenderer(name, str_value, attrs, list(chain(self.choices, choices)))
|
||||
final_attrs = self.build_attrs(attrs)
|
||||
return RadioFieldRenderer(name, str_value, final_attrs, list(chain(self.choices, choices)))
|
||||
|
||||
def id_for_label(self, id_):
|
||||
# RadioSelect is represented by multiple <input type="radio"> fields,
|
||||
@ -327,14 +327,25 @@ class MultiWidget(Widget):
|
||||
if not isinstance(value, list):
|
||||
value = self.decompress(value)
|
||||
output = []
|
||||
final_attrs = self.build_attrs(attrs)
|
||||
id_ = final_attrs.get('id', None)
|
||||
for i, widget in enumerate(self.widgets):
|
||||
try:
|
||||
widget_value = value[i]
|
||||
except KeyError:
|
||||
except IndexError:
|
||||
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)
|
||||
|
||||
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):
|
||||
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))
|
||||
upto = match.end()
|
||||
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
|
||||
|
||||
def resolve(self, context, ignore_failures=False):
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
from django.template import resolve_variable, Library
|
||||
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
|
||||
import re
|
||||
import random as random_module
|
||||
@ -501,12 +501,12 @@ def filesizeformat(bytes):
|
||||
return u"0 bytes"
|
||||
|
||||
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:
|
||||
return u"%.1f KB" % (bytes / 1024)
|
||||
return ugettext("%.1f KB") % (bytes / 1024)
|
||||
if bytes < 1024 * 1024 * 1024:
|
||||
return u"%.1f MB" % (bytes / (1024 * 1024))
|
||||
return u"%.1f GB" % (bytes / (1024 * 1024 * 1024))
|
||||
return ugettext("%.1f MB") % (bytes / (1024 * 1024))
|
||||
return ugettext("%.1f GB") % (bytes / (1024 * 1024 * 1024))
|
||||
|
||||
def pluralize(value, arg=u's'):
|
||||
"""
|
||||
|
@ -957,6 +957,7 @@ def url(parser, token):
|
||||
for arg in bits[2].split(','):
|
||||
if '=' in arg:
|
||||
k, v = arg.split('=', 1)
|
||||
k = k.strip()
|
||||
kwargs[k] = parser.compile_filter(v)
|
||||
else:
|
||||
args.append(parser.compile_filter(arg))
|
||||
|
@ -99,6 +99,13 @@ class SortedDict(dict):
|
||||
obj.keyOrder = self.keyOrder
|
||||
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):
|
||||
pass
|
||||
|
||||
@ -211,7 +218,7 @@ class MultiValueDict(dict):
|
||||
def update(self, *args, **kwargs):
|
||||
"update() extends rather than replaces existing key lists. Also accepts keyword args."
|
||||
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:
|
||||
other_dict = args[0]
|
||||
if isinstance(other_dict, MultiValueDict):
|
||||
|
@ -24,7 +24,6 @@ class RWLock:
|
||||
writer_enters()
|
||||
writer_leaves()
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.mutex = threading.RLock()
|
||||
self.can_read = threading.Semaphore(0)
|
||||
|
@ -1,6 +1,6 @@
|
||||
import datetime, math, time
|
||||
from django.utils.tzinfo import LocalTimezone
|
||||
from django.utils.translation import ungettext
|
||||
from django.utils.translation import ungettext, ugettext
|
||||
|
||||
def timesince(d, now=None):
|
||||
"""
|
||||
@ -37,14 +37,14 @@ def timesince(d, now=None):
|
||||
if count != 0:
|
||||
break
|
||||
if count < 0:
|
||||
return u'%d milliseconds' % math.floor((now - d).microseconds / 1000)
|
||||
s = u'%d %s' % (count, name(count))
|
||||
return ugettext('%d milliseconds') % math.floor((now - d).microseconds / 1000)
|
||||
s = ugettext('%(number)d %(type)s') % {'number': count, 'type': name(count)}
|
||||
if i + 1 < len(chunks):
|
||||
# Now get the second item
|
||||
seconds2, name2 = chunks[i + 1]
|
||||
count2 = (since - (seconds * count)) / seconds2
|
||||
if count2 != 0:
|
||||
s += ', %d %s' % (count2, name2(count2))
|
||||
s += ugettext(', %(number)d %(type)s') % {'number': count2, 'type': name2(count2)}
|
||||
return s
|
||||
|
||||
def timeuntil(d, now=None):
|
||||
|
@ -100,14 +100,14 @@ change:
|
||||
|
||||
.. _caching: ../cache/
|
||||
.. _custom template tags and libraries: ../templates_python/
|
||||
.. _database lookup: ../db_api/
|
||||
.. _database lookup: ../db-api/
|
||||
.. _django-admin utility: ../django-admin/
|
||||
.. _fastcgi integration: ../fastcgi/
|
||||
.. _flatpages: ../flatpages/
|
||||
.. _generic views: ../generic_views/
|
||||
.. _internationalization: ../i18n/
|
||||
.. _legacy database integration: ../legacy_databases/
|
||||
.. _model definition: ../model_api/
|
||||
.. _model definition: ../model-api/
|
||||
.. _mod_python integration: ../modpython/
|
||||
.. _redirects: ../redirects/
|
||||
.. _request/response objects: ../request_response/
|
||||
|
@ -144,7 +144,7 @@ custom methods:
|
||||
Raises ``django.contrib.auth.models.SiteProfileNotAvailable`` if the current site
|
||||
doesn't allow profiles.
|
||||
|
||||
.. _Django model: ../model_api/
|
||||
.. _Django model: ../model-api/
|
||||
.. _DEFAULT_FROM_EMAIL: ../settings/#default-from-email
|
||||
|
||||
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.
|
||||
|
||||
Hashtype is either ``sha1`` (default) or ``md5`` -- the algorithm used to
|
||||
perform a one-way hash of the password. Salt is a random string used to salt
|
||||
the raw password to create the hash.
|
||||
Hashtype is either ``sha1`` (default), ``md5`` or ``crypt`` -- the algorithm
|
||||
used to perform a one-way hash of the password. Salt is a random string used
|
||||
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::
|
||||
|
||||
@ -387,14 +389,15 @@ introduced in Python 2.4::
|
||||
|
||||
``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:
|
||||
* If the user isn't logged in, redirect to ``settings.LOGIN_URL``
|
||||
(``/accounts/login/`` by default), 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.
|
||||
|
||||
Note that you'll need to map the appropriate Django view to ``/accounts/login/``.
|
||||
To do this, add the following line to your URLconf::
|
||||
Note that you'll need to map the appropriate Django view to ``settings.LOGIN_URL``.
|
||||
For example, using the defaults, add the following line to your URLconf::
|
||||
|
||||
(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
|
||||
successful, the view redirects to the URL specified in ``next``. If
|
||||
``next`` isn't provided, it redirects to ``/accounts/profile/`` (which is
|
||||
currently hard-coded). If login isn't successful, it redisplays the login
|
||||
form.
|
||||
``next`` isn't provided, it redirects to ``settings.LOGIN_REDIRECT_URL``
|
||||
(which defaults to ``/accounts/profile/``). If login isn't successful,
|
||||
it redisplays the login form.
|
||||
|
||||
It's your responsibility to provide the login form in a template called
|
||||
``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:**
|
||||
|
||||
* ``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``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -569,7 +572,7 @@ successful login.
|
||||
**Optional arguments:**
|
||||
|
||||
* ``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
|
||||
---------------------
|
||||
@ -636,7 +639,7 @@ Note that ``user_passes_test`` does not automatically check that the ``User``
|
||||
is not anonymous.
|
||||
|
||||
``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::
|
||||
|
||||
@ -680,7 +683,7 @@ parameter. Example::
|
||||
my_view = permission_required('polls.can_vote', login_url='/loginpage/')(my_view)
|
||||
|
||||
As in the ``login_required`` decorator, ``login_url`` defaults to
|
||||
``'/accounts/login/'``.
|
||||
``settings.LOGIN_URL``.
|
||||
|
||||
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
|
||||
``syncdb``.
|
||||
|
||||
.. _model Meta attribute: ../model_api/#meta-options
|
||||
.. _model Meta attribute: ../model-api/#meta-options
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
`AutoField documentation`_.)
|
||||
|
||||
.. _AutoField documentation: ../model_api/#autofield
|
||||
.. _AutoField documentation: ../model-api/#autofield
|
||||
|
||||
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
|
||||
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
|
||||
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?
|
||||
-----------------------------
|
||||
|
@ -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 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 database API: ../db_api/
|
||||
.. _Django database API: ../db-api/
|
||||
|
||||
Flatpage templates
|
||||
==================
|
||||
|
@ -691,5 +691,5 @@ fails. If no message is passed in, a default message is used.
|
||||
document for more details).
|
||||
|
||||
.. _`generic views`: ../generic_views/
|
||||
.. _`models API`: ../model_api/
|
||||
.. _`models API`: ../model-api/
|
||||
.. _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
|
||||
lambda that returns the QuerySet.
|
||||
|
||||
.. _database API docs: ../db_api/
|
||||
.. _database API docs: ../db-api/
|
||||
|
||||
"Simple" generic views
|
||||
======================
|
||||
|
@ -175,7 +175,7 @@ class, though::
|
||||
verbose_name = _('my thing')
|
||||
verbose_name_plural = _('mythings')
|
||||
|
||||
.. _Django models: ../model_api/
|
||||
.. _Django models: ../model-api/
|
||||
|
||||
Pluralization
|
||||
~~~~~~~~~~~~~
|
||||
|
@ -194,14 +194,23 @@ This doesn't accept ``maxlength``; its ``maxlength`` is automatically set to
|
||||
``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`_,
|
||||
which will be replaced by the date/time of the file upload (so that
|
||||
uploaded files don't fill up the given directory).
|
||||
====================== ===================================================
|
||||
Argument Description
|
||||
====================== ===================================================
|
||||
``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
|
||||
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
|
||||
on the filesystem. Has three special arguments, of which the first is
|
||||
required:
|
||||
**required**:
|
||||
|
||||
====================== ===================================================
|
||||
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
|
||||
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 database API: ../db_api/
|
||||
.. _Django database API: ../db-api/
|
||||
|
@ -93,6 +93,7 @@ All attributes except ``session`` should be considered read-only.
|
||||
* ``CONTENT_TYPE``
|
||||
* ``HTTP_ACCEPT_ENCODING``
|
||||
* ``HTTP_ACCEPT_LANGUAGE``
|
||||
* ``HTTP_HOST`` -- The HTTP Host header sent by the client.
|
||||
* ``HTTP_REFERER`` -- The referring page, if any.
|
||||
* ``HTTP_USER_AGENT`` -- The client's user-agent 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,
|
||||
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::
|
||||
|
||||
|
@ -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
|
||||
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
|
||||
--------
|
||||
|
||||
@ -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,
|
||||
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
|
||||
-----------
|
||||
|
||||
@ -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
|
||||
exist (see the ``verify_exists`` option on URLField_).
|
||||
|
||||
.. _URLField: ../model_api/#urlfield
|
||||
.. _URLField: ../model-api/#urlfield
|
||||
|
||||
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
|
||||
``DJANGO_SETTINGS_MODULE``. Not both, and not neither.
|
||||
|
||||
.. _@login_required: ../authentication/#the-login-required-decorator
|
||||
|
||||
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
|
||||
``CurrentSiteManager``.
|
||||
|
||||
.. _manager: ../model_api/#managers
|
||||
.. _manager documentation: ../model_api/#managers
|
||||
.. _manager: ../model-api/#managers
|
||||
.. _manager documentation: ../model-api/#managers
|
||||
|
||||
How Django uses the sites framework
|
||||
===================================
|
||||
|
@ -159,7 +159,7 @@ put into those elements.
|
||||
{{ obj.description }}
|
||||
|
||||
.. _chicagocrime.org: http://www.chicagocrime.org/
|
||||
.. _object-relational mapper: ../db_api/
|
||||
.. _object-relational mapper: ../db-api/
|
||||
.. _Django templates: ../templates/
|
||||
|
||||
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
|
||||
Django's automatic admin working.
|
||||
|
||||
.. _Database API reference: ../db_api/
|
||||
.. _Database API reference: ../db-api/
|
||||
.. _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
|
||||
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
|
||||
that contains the ``poll`` and ``latest_poll_list`` context variables. However,
|
||||
|
@ -52,6 +52,8 @@
|
||||
'not one'
|
||||
>>> d.keys() == d.copy().keys()
|
||||
True
|
||||
>>> print repr(d)
|
||||
{'one': 'not one', 'two': 'two', 'three': 'three'}
|
||||
|
||||
### 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
|
||||
|
||||
# Unicode choices are correctly rendered as HTML
|
||||
>>> w = RadioSelect()
|
||||
>>> 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>'
|
||||
|
||||
# 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 ###############################################
|
||||
|
||||
>>> 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" />'
|
||||
>>> 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" />'
|
||||
>>> 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 #########################################################
|
||||
|
||||
|
@ -700,7 +700,7 @@ class Templates(unittest.TestCase):
|
||||
### URL TAG ########################################################
|
||||
# Successes
|
||||
'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/'),
|
||||
'url04' : ('{% url named-client client.id %}', {'client': {'id': 1}}, '/url_tag/named-client/1/'),
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user