1
0
mirror of https://github.com/django/django.git synced 2025-07-04 17:59:13 +00:00

boulder-oracle-sprint: Merged to [5099]

git-svn-id: http://code.djangoproject.com/svn/django/branches/boulder-oracle-sprint@5100 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Boulder Sprinters 2007-04-26 20:45:53 +00:00
parent 61bef9bbfd
commit d0213969c2
53 changed files with 828 additions and 119 deletions

View File

@ -150,6 +150,7 @@ answer newbie questions, and generally made Django that much better:
Manuzhai Manuzhai
Petar Marić <http://www.petarmaric.com/> Petar Marić <http://www.petarmaric.com/>
Nuno Mariz <nmariz@gmail.com> Nuno Mariz <nmariz@gmail.com>
marijn@metronomo.cl
mark@junklight.com mark@junklight.com
Yasushi Masuda <whosaysni@gmail.com> Yasushi Masuda <whosaysni@gmail.com>
mattycakes@gmail.com mattycakes@gmail.com
@ -167,6 +168,7 @@ answer newbie questions, and generally made Django that much better:
Sam Newman <http://www.magpiebrain.com/> Sam Newman <http://www.magpiebrain.com/>
Neal Norwitz <nnorwitz@google.com> Neal Norwitz <nnorwitz@google.com>
oggie rob <oz.robharvey@gmail.com> oggie rob <oz.robharvey@gmail.com>
onaiort@gmail.com
Jay Parlar <parlar@gmail.com> Jay Parlar <parlar@gmail.com>
pavithran s <pavithran.s@gmail.com> pavithran s <pavithran.s@gmail.com>
Barry Pederson <bp@barryp.org> Barry Pederson <bp@barryp.org>

View File

@ -81,7 +81,7 @@ def make_messages():
src = pythonize_re.sub('\n#', src) src = pythonize_re.sub('\n#', src)
open(os.path.join(dirpath, '%s.py' % file), "wb").write(src) open(os.path.join(dirpath, '%s.py' % file), "wb").write(src)
thefile = '%s.py' % file thefile = '%s.py' % file
cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy --from-code UTF-8 -o - "%s"' % ( cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile)) os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile))
(stdin, stdout, stderr) = os.popen3(cmd, 'b') (stdin, stdout, stderr) = os.popen3(cmd, 'b')
msgs = stdout.read() msgs = stdout.read()
@ -103,7 +103,7 @@ def make_messages():
open(os.path.join(dirpath, '%s.py' % file), "wb").write(templatize(src)) open(os.path.join(dirpath, '%s.py' % file), "wb").write(templatize(src))
thefile = '%s.py' % file thefile = '%s.py' % file
if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
cmd = 'xgettext %s -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy --from-code UTF-8 -o - "%s"' % ( cmd = 'xgettext %s -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile)) os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile))
(stdin, stdout, stderr) = os.popen3(cmd, 'b') (stdin, stdout, stderr) = os.popen3(cmd, 'b')
msgs = stdout.read() msgs = stdout.read()

View File

@ -22,7 +22,7 @@ def gather_stats(p):
else: else:
continue continue
print "Processing %s" % f print "Processing %s" % f
if profiles.has_key(path): if path in profiles:
profiles[path].add(prof) profiles[path].add(prof)
else: else:
profiles[path] = prof profiles[path] = prof

View File

@ -11,9 +11,10 @@ def patterns(prefix, *args):
pattern_list = [] pattern_list = []
for t in args: for t in args:
if isinstance(t, (list, tuple)): if isinstance(t, (list, tuple)):
pattern_list.append(url(prefix=prefix, *t)) t = url(prefix=prefix, *t)
else: elif isinstance(t, RegexURLPattern):
pattern_list.append(t) t.add_prefix(prefix)
pattern_list.append(t)
return pattern_list return pattern_list
def url(regex, view, kwargs=None, name=None, prefix=''): def url(regex, view, kwargs=None, name=None, prefix=''):

View File

@ -74,7 +74,7 @@ class FieldWidgetNode(template.Node):
self.bound_field_var = bound_field_var self.bound_field_var = bound_field_var
def get_nodelist(cls, klass): def get_nodelist(cls, klass):
if not cls.nodelists.has_key(klass): if klass not in cls.nodelists:
try: try:
field_class_name = klass.__name__ field_class_name = klass.__name__
template_name = "widget/%s.html" % class_name_to_underscored(field_class_name) template_name = "widget/%s.html" % class_name_to_underscored(field_class_name)

View File

@ -17,7 +17,7 @@ def user_add_stage(request):
if not errors: if not errors:
new_user = manipulator.save(new_data) new_user = manipulator.save(new_data)
msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': 'user', 'obj': new_user} msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': 'user', 'obj': new_user}
if request.POST.has_key("_addanother"): if "_addanother" in request.POST:
request.user.message_set.create(message=msg) request.user.message_set.create(message=msg)
return HttpResponseRedirect(request.path) return HttpResponseRedirect(request.path)
else: else:
@ -29,7 +29,7 @@ def user_add_stage(request):
return render_to_response('admin/auth/user/add_form.html', { return render_to_response('admin/auth/user/add_form.html', {
'title': _('Add user'), 'title': _('Add user'),
'form': form, 'form': form,
'is_popup': request.REQUEST.has_key('_popup'), 'is_popup': '_popup' in request.REQUEST,
'add': True, 'add': True,
'change': False, 'change': False,
'has_delete_permission': False, 'has_delete_permission': False,
@ -63,7 +63,7 @@ def user_change_password(request, id):
return render_to_response('admin/auth/user/change_password.html', { return render_to_response('admin/auth/user/change_password.html', {
'title': _('Change password: %s') % escape(user.username), 'title': _('Change password: %s') % escape(user.username),
'form': form, 'form': form,
'is_popup': request.REQUEST.has_key('_popup'), 'is_popup': '_popup' in request.REQUEST,
'add': True, 'add': True,
'change': False, 'change': False,
'has_delete_permission': False, 'has_delete_permission': False,

View File

@ -12,7 +12,7 @@ LOGIN_FORM_KEY = 'this_is_the_login_form'
def _display_login_form(request, error_message=''): def _display_login_form(request, error_message=''):
request.session.set_test_cookie() request.session.set_test_cookie()
if request.POST and request.POST.has_key('post_data'): if request.POST and 'post_data' in request.POST:
# User has failed login BUT has previously saved post data. # User has failed login BUT has previously saved post data.
post_data = request.POST['post_data'] post_data = request.POST['post_data']
elif request.POST: elif request.POST:
@ -48,7 +48,7 @@ def staff_member_required(view_func):
def _checklogin(request, *args, **kwargs): def _checklogin(request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_staff: if request.user.is_authenticated() and request.user.is_staff:
# The user is valid. Continue to the admin page. # The user is valid. Continue to the admin page.
if request.POST.has_key('post_data'): if 'post_data' in request.POST:
# User must have re-authenticated through a different window # User must have re-authenticated through a different window
# or tab. # or tab.
request.POST = _decode_post_data(request.POST['post_data']) request.POST = _decode_post_data(request.POST['post_data'])
@ -57,7 +57,7 @@ def staff_member_required(view_func):
assert hasattr(request, 'session'), "The Django admin requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'." assert hasattr(request, 'session'), "The Django admin requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'."
# If this isn't already the login page, display it. # If this isn't already the login page, display it.
if not request.POST.has_key(LOGIN_FORM_KEY): if LOGIN_FORM_KEY not in request.POST:
if request.POST: if request.POST:
message = _("Please log in again, because your session has expired. Don't worry: Your submission has been saved.") message = _("Please log in again, because your session has expired. Don't worry: Your submission has been saved.")
else: else:
@ -90,9 +90,9 @@ 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.
if request.POST.has_key('post_data'): if 'post_data' in request.POST:
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 LOGIN_FORM_KEY not in post_data:
# overwrite request.POST with the saved post_data, and continue # overwrite request.POST with the saved post_data, and continue
request.POST = post_data request.POST = post_data
request.user = user request.user = user

View File

@ -257,17 +257,17 @@ def add_stage(request, app_label, model_name, show_delete=False, form_url='', po
msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': opts.verbose_name, 'obj': new_object} msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': opts.verbose_name, 'obj': new_object}
# Here, we distinguish between different save types by checking for # Here, we distinguish between different save types by checking for
# the presence of keys in request.POST. # the presence of keys in request.POST.
if request.POST.has_key("_continue"): if "_continue" in request.POST:
request.user.message_set.create(message=msg + ' ' + _("You may edit it again below.")) request.user.message_set.create(message=msg + ' ' + _("You may edit it again below."))
if request.POST.has_key("_popup"): if "_popup" in request.POST:
post_url_continue += "?_popup=1" post_url_continue += "?_popup=1"
return HttpResponseRedirect(post_url_continue % pk_value) return HttpResponseRedirect(post_url_continue % pk_value)
if request.POST.has_key("_popup"): if "_popup" in request.POST:
if type(pk_value) is str: # Quote if string, so JavaScript doesn't think it's a variable. if type(pk_value) is str: # Quote if string, so JavaScript doesn't think it's a variable.
pk_value = '"%s"' % pk_value.replace('"', '\\"') pk_value = '"%s"' % pk_value.replace('"', '\\"')
return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %s, "%s");</script>' % \ return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %s, "%s");</script>' % \
(pk_value, str(new_object).replace('"', '\\"'))) (pk_value, str(new_object).replace('"', '\\"')))
elif request.POST.has_key("_addanother"): elif "_addanother" in request.POST:
request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name)) request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
return HttpResponseRedirect(request.path) return HttpResponseRedirect(request.path)
else: else:
@ -288,7 +288,7 @@ def add_stage(request, app_label, model_name, show_delete=False, form_url='', po
c = template.RequestContext(request, { c = template.RequestContext(request, {
'title': _('Add %s') % opts.verbose_name, 'title': _('Add %s') % opts.verbose_name,
'form': form, 'form': form,
'is_popup': request.REQUEST.has_key('_popup'), 'is_popup': '_popup' in request.REQUEST,
'show_delete': show_delete, 'show_delete': show_delete,
}) })
@ -308,7 +308,7 @@ def change_stage(request, app_label, model_name, object_id):
if not request.user.has_perm(app_label + '.' + opts.get_change_permission()): if not request.user.has_perm(app_label + '.' + opts.get_change_permission()):
raise PermissionDenied raise PermissionDenied
if request.POST and request.POST.has_key("_saveasnew"): if request.POST and "_saveasnew" in request.POST:
return add_stage(request, app_label, model_name, form_url='../../add/') return add_stage(request, app_label, model_name, form_url='../../add/')
try: try:
@ -343,16 +343,16 @@ def change_stage(request, app_label, model_name, object_id):
LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, pk_value, str(new_object), CHANGE, change_message) LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, pk_value, str(new_object), CHANGE, change_message)
msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object} msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object}
if request.POST.has_key("_continue"): if "_continue" in request.POST:
request.user.message_set.create(message=msg + ' ' + _("You may edit it again below.")) request.user.message_set.create(message=msg + ' ' + _("You may edit it again below."))
if request.REQUEST.has_key('_popup'): if '_popup' in request.REQUEST:
return HttpResponseRedirect(request.path + "?_popup=1") return HttpResponseRedirect(request.path + "?_popup=1")
else: else:
return HttpResponseRedirect(request.path) return HttpResponseRedirect(request.path)
elif request.POST.has_key("_saveasnew"): elif "_saveasnew" in request.POST:
request.user.message_set.create(message=_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': opts.verbose_name, 'obj': new_object}) request.user.message_set.create(message=_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': opts.verbose_name, 'obj': new_object})
return HttpResponseRedirect("../%s/" % pk_value) return HttpResponseRedirect("../%s/" % pk_value)
elif request.POST.has_key("_addanother"): elif "_addanother" in request.POST:
request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name)) request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
return HttpResponseRedirect("../add/") return HttpResponseRedirect("../add/")
else: else:
@ -392,7 +392,7 @@ def change_stage(request, app_label, model_name, object_id):
'form': form, 'form': form,
'object_id': object_id, 'object_id': object_id,
'original': manipulator.original_object, 'original': manipulator.original_object,
'is_popup': request.REQUEST.has_key('_popup'), 'is_popup': '_popup' in request.REQUEST,
}) })
return render_change_form(model, manipulator, c, change=True) return render_change_form(model, manipulator, c, change=True)
change_stage = staff_member_required(never_cache(change_stage)) change_stage = staff_member_required(never_cache(change_stage))
@ -558,12 +558,12 @@ class ChangeList(object):
self.page_num = int(request.GET.get(PAGE_VAR, 0)) self.page_num = int(request.GET.get(PAGE_VAR, 0))
except ValueError: except ValueError:
self.page_num = 0 self.page_num = 0
self.show_all = request.GET.has_key(ALL_VAR) self.show_all = ALL_VAR in request.GET
self.is_popup = request.GET.has_key(IS_POPUP_VAR) self.is_popup = IS_POPUP_VAR in request.GET
self.params = dict(request.GET.items()) self.params = dict(request.GET.items())
if self.params.has_key(PAGE_VAR): if PAGE_VAR in self.params:
del self.params[PAGE_VAR] del self.params[PAGE_VAR]
if self.params.has_key(ERROR_FLAG): if ERROR_FLAG in self.params:
del self.params[ERROR_FLAG] del self.params[ERROR_FLAG]
self.order_field, self.order_type = self.get_ordering() self.order_field, self.order_type = self.get_ordering()
@ -594,7 +594,7 @@ class ChangeList(object):
if k.startswith(r): if k.startswith(r):
del p[k] del p[k]
for k, v in new_params.items(): for k, v in new_params.items():
if p.has_key(k) and v is None: if k in p and v is None:
del p[k] del p[k]
elif v is not None: elif v is not None:
p[k] = v p[k] = v
@ -656,7 +656,7 @@ class ChangeList(object):
order_field, order_type = ordering[0][1:], 'desc' order_field, order_type = ordering[0][1:], 'desc'
else: else:
order_field, order_type = ordering[0], 'asc' order_field, order_type = ordering[0], 'asc'
if params.has_key(ORDER_VAR): if ORDER_VAR in params:
try: try:
field_name = lookup_opts.admin.list_display[int(params[ORDER_VAR])] field_name = lookup_opts.admin.list_display[int(params[ORDER_VAR])]
try: try:
@ -674,7 +674,7 @@ class ChangeList(object):
order_field = f.name order_field = f.name
except (IndexError, ValueError): except (IndexError, ValueError):
pass # Invalid ordering specified. Just use the default. pass # Invalid ordering specified. Just use the default.
if params.has_key(ORDER_TYPE_VAR) and params[ORDER_TYPE_VAR] in ('asc', 'desc'): if ORDER_TYPE_VAR in params and params[ORDER_TYPE_VAR] in ('asc', 'desc'):
order_type = params[ORDER_TYPE_VAR] order_type = params[ORDER_TYPE_VAR]
return order_field, order_type return order_field, order_type
@ -682,7 +682,7 @@ class ChangeList(object):
qs = self.manager.get_query_set() qs = self.manager.get_query_set()
lookup_params = self.params.copy() # a dictionary of the query string lookup_params = self.params.copy() # a dictionary of the query string
for i in (ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, IS_POPUP_VAR): for i in (ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, IS_POPUP_VAR):
if lookup_params.has_key(i): if i in lookup_params:
del lookup_params[i] del lookup_params[i]
# Apply lookup parameters from the query string. # Apply lookup parameters from the query string.

View File

@ -116,7 +116,7 @@ class CommentListNode(template.Node):
comment_list = get_list_function(**kwargs).order_by(self.ordering + 'submit_date').select_related() comment_list = get_list_function(**kwargs).order_by(self.ordering + 'submit_date').select_related()
if not self.free: if not self.free:
if context.has_key('user') and context['user'].is_authenticated(): if 'user' in context and context['user'].is_authenticated():
user_id = context['user'].id user_id = context['user'].id
context['user_can_moderate_comments'] = Comment.objects.user_is_moderator(context['user']) context['user_can_moderate_comments'] = Comment.objects.user_is_moderator(context['user'])
else: else:

View File

@ -217,10 +217,10 @@ def post_comment(request):
errors = manipulator.get_validation_errors(new_data) errors = manipulator.get_validation_errors(new_data)
# If user gave correct username/password and wasn't already logged in, log them in # If user gave correct username/password and wasn't already logged in, log them in
# so they don't have to enter a username/password again. # so they don't have to enter a username/password again.
if manipulator.get_user() and not manipulator.get_user().is_authenticated() and new_data.has_key('password') and manipulator.get_user().check_password(new_data['password']): if manipulator.get_user() and not manipulator.get_user().is_authenticated() and 'password' in new_data and manipulator.get_user().check_password(new_data['password']):
from django.contrib.auth import login from django.contrib.auth import login
login(request, manipulator.get_user()) login(request, manipulator.get_user())
if errors or request.POST.has_key('preview'): if errors or 'preview' in request.POST:
class CommentFormWrapper(oldforms.FormWrapper): class CommentFormWrapper(oldforms.FormWrapper):
def __init__(self, manipulator, new_data, errors, rating_choices): def __init__(self, manipulator, new_data, errors, rating_choices):
oldforms.FormWrapper.__init__(self, manipulator, new_data, errors) oldforms.FormWrapper.__init__(self, manipulator, new_data, errors)
@ -244,7 +244,7 @@ def post_comment(request):
'rating_range': rating_range, 'rating_range': rating_range,
'rating_choices': rating_choices, 'rating_choices': rating_choices,
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
elif request.POST.has_key('post'): elif 'post' in request.POST:
# If the IP is banned, mail the admins, do NOT save the comment, and # If the IP is banned, mail the admins, do NOT save the comment, and
# serve up the "Thanks for posting" page as if the comment WAS posted. # serve up the "Thanks for posting" page as if the comment WAS posted.
if request.META['REMOTE_ADDR'] in settings.BANNED_IPS: if request.META['REMOTE_ADDR'] in settings.BANNED_IPS:
@ -298,7 +298,7 @@ def post_free_comment(request):
new_data['is_public'] = IS_PUBLIC in option_list new_data['is_public'] = IS_PUBLIC in option_list
manipulator = PublicFreeCommentManipulator() manipulator = PublicFreeCommentManipulator()
errors = manipulator.get_validation_errors(new_data) errors = manipulator.get_validation_errors(new_data)
if errors or request.POST.has_key('preview'): if errors or 'preview' in request.POST:
comment = errors and '' or manipulator.get_comment(new_data) comment = errors and '' or manipulator.get_comment(new_data)
return render_to_response('comments/free_preview.html', { return render_to_response('comments/free_preview.html', {
'comment': comment, 'comment': comment,
@ -307,7 +307,7 @@ def post_free_comment(request):
'target': target, 'target': target,
'hash': security_hash, 'hash': security_hash,
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
elif request.POST.has_key('post'): elif 'post' in request.POST:
# If the IP is banned, mail the admins, do NOT save the comment, and # If the IP is banned, mail the admins, do NOT save the comment, and
# serve up the "Thanks for posting" page as if the comment WAS posted. # serve up the "Thanks for posting" page as if the comment WAS posted.
if request.META['REMOTE_ADDR'] in settings.BANNED_IPS: if request.META['REMOTE_ADDR'] in settings.BANNED_IPS:
@ -330,7 +330,7 @@ def comment_was_posted(request):
The object the comment was posted on The object the comment was posted on
""" """
obj = None obj = None
if request.GET.has_key('c'): if 'c' in request.GET:
content_type_id, object_id = request.GET['c'].split(':') content_type_id, object_id = request.GET['c'].split(':')
try: try:
content_type = ContentType.objects.get(pk=content_type_id) content_type = ContentType.objects.get(pk=content_type_id)

View File

@ -4,7 +4,7 @@ BR-specific Form helpers
""" """
from django.newforms import ValidationError from django.newforms import ValidationError
from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES from django.newforms.fields import Field, RegexField, CharField, Select, EMPTY_VALUES
from django.utils.encoding import smart_unicode from django.utils.encoding import smart_unicode
from django.utils.translation import gettext from django.utils.translation import gettext
import re import re
@ -15,7 +15,7 @@ class BRZipCodeField(RegexField):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(BRZipCodeField, self).__init__(r'^\d{5}-\d{3}$', super(BRZipCodeField, self).__init__(r'^\d{5}-\d{3}$',
max_length=None, min_length=None, max_length=None, min_length=None,
error_message=gettext(u'Enter a zip code in the format XXXXX-XXX.'), error_message=gettext('Enter a zip code in the format XXXXX-XXX.'),
*args, **kwargs) *args, **kwargs)
class BRPhoneNumberField(Field): class BRPhoneNumberField(Field):
@ -31,9 +31,89 @@ class BRPhoneNumberField(Field):
class BRStateSelect(Select): class BRStateSelect(Select):
""" """
A Select widget that uses a list of brazilian states/territories A Select widget that uses a list of Brazilian states/territories
as its choices. as its choices.
""" """
def __init__(self, attrs=None): def __init__(self, attrs=None):
from br_states import STATE_CHOICES # relative import from br_states import STATE_CHOICES # relative import
super(BRStateSelect, self).__init__(attrs, choices=STATE_CHOICES) super(BRStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
def DV_maker(v):
if v >= 2:
return 11 - v
return 0
class BRCPFField(CharField):
"""
This field validate a CPF number or a CPF string. A CPF number is
compounded by XXX.XXX.XXX-VD. The two last digits are check digits.
More information:
http://en.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas
"""
def __init__(self, *args, **kwargs):
super(BRCPFField, self).__init__(max_length=14, min_length=11, *args, **kwargs)
def clean(self, value):
"""
Value can be either a string in the format XXX.XXX.XXX-XX or an
11-digit number.
"""
value = super(BRCPFField, self).clean(value)
if value in EMPTY_VALUES:
return u''
orig_value = value[:]
if not value.isdigit():
value = re.sub("[-\.]", "", value)
try:
int(value)
except ValueError:
raise ValidationError(gettext("This field requires only numbers."))
if len(value) != 11:
raise ValidationError(gettext("This field requires at most 11 digits or 14 characters."))
orig_dv = value[-2:]
new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(10, 1, -1))])
new_1dv = DV_maker(new_1dv % 11)
value = value[:-2] + str(new_1dv) + value[-1]
new_2dv = sum([i * int(value[idx]) for idx, i in enumerate(range(11, 1, -1))])
new_2dv = DV_maker(new_2dv % 11)
value = value[:-1] + str(new_2dv)
if value[-2:] != orig_dv:
raise ValidationError(gettext("Invalid CPF number."))
return orig_value
class BRCNPJField(Field):
def clean(self, value):
"""
Value can be either a string in the format XX.XXX.XXX/XXXX-XX or a
group of 14 characters.
"""
value = super(BRCNPJField, self).clean(value)
if value in EMPTY_VALUES:
return u''
orig_value = value[:]
if not value.isdigit():
value = re.sub("[-/\.]", "", value)
try:
int(value)
except ValueError:
raise ValidationError("This field requires only numbers.")
if len(value) != 14:
raise ValidationError(
gettext("This field requires at least 14 digits"))
orig_dv = value[-2:]
new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(5, 1, -1) + range(9, 1, -1))])
new_1dv = DV_maker(new_1dv % 11)
value = value[:-2] + str(new_1dv) + value[-1]
new_2dv = sum([i * int(value[idx]) for idx, i in enumerate(range(6, 1, -1) + range(9, 1, -1))])
new_2dv = DV_maker(new_2dv % 11)
value = value[:-1] + str(new_2dv)
if value[-2:] != orig_dv:
raise ValidationError(gettext("Invalid CNPJ number."))
return orig_value

View File

@ -0,0 +1,78 @@
"""
Chile specific form helpers.
"""
from django.newforms import ValidationError
from django.newforms.fields import RegexField, EMPTY_VALUES
from django.utils.translation import gettext
class CLRutField(RegexField):
"""
Chilean "Rol Unico Tributario" (RUT) field. This is the Chilean national
identification number.
Samples for testing are available from
https://palena.sii.cl/cvc/dte/ee_empresas_emisoras.html
"""
def __init__(self, *args, **kwargs):
if 'strict' in kwargs:
del kwargs['strict']
super(CLRutField, self).__init__(r'^(\d{1,2}\.)?\d{3}\.\d{3}-[\dkK]$',
error_message=gettext('Enter valid a Chilean RUT. The format is XX.XXX.XXX-X.'),
*args, **kwargs)
else:
# In non-strict mode, accept RUTs that validate but do not exist in
# the real world.
super(CLRutField, self).__init__(r'^[\d\.]{1,11}-?[\dkK]$', error_message=gettext(u'Enter valid a Chilean RUT'), *args, **kwargs)
def clean(self, value):
"""
Check and clean the Chilean RUT.
"""
super(CLRutField, self).clean(value)
if value in EMPTY_VALUES:
return u''
rut, verificador = self._canonify(value)
if self._algorithm(rut) == verificador:
return self._format(rut, verificador)
else:
raise ValidationError(u'The Chilean RUT is not valid.')
def _algorithm(self, rut):
"""
Takes RUT in pure canonical form, calculates the verifier digit.
"""
suma = 0
multi = 2
for r in rut[::-1]:
suma += int(r) * multi
multi += 1
if multi == 8:
multi = 2
return '0123456789K0'[11 - suma % 11]
def _canonify(self, rut):
"""
Turns the RUT into one normalized format. Returns a (rut, verifier)
tuple.
"""
rut = str(rut).replace(' ', '').replace('.', '').replace('-', '')
return rut[:-1], rut[-1]
def _format(self, code, verifier=None):
"""
Formats the RUT from canonical form to the common string representation.
If verifier=None, then the last digit in 'code' is the verifier.
"""
if verifier is None:
verifier = code[-1]
code = code[:-1]
while len(code) > 3 and '.' not in code[:3]:
pos = code.find('.')
if pos == -1:
new_dot = -3
else:
new_dot = pos - 3
code = code[:new_dot] + '.' + code[new_dot:]
return '%s-%s' % (code, verifier)

View File

@ -0,0 +1,77 @@
"""
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)

View 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')
)

View File

@ -16,7 +16,7 @@ def index(request, sitemaps):
def sitemap(request, sitemaps, section=None): def sitemap(request, sitemaps, section=None):
maps, urls = [], [] maps, urls = [], []
if section is not None: if section is not None:
if not sitemaps.has_key(section): if section not in sitemaps:
raise Http404("No sitemap available for section: %r" % section) raise Http404("No sitemap available for section: %r" % section)
maps.append(sitemaps[section]) maps.append(sitemaps[section])
else: else:

View File

@ -52,7 +52,7 @@ class CacheClass(BaseCache):
pass pass
def has_key(self, key): def has_key(self, key):
return self._cache.has_key(key) return key in self._cache
def _cull(self): def _cull(self):
if self._cull_frequency == 0: if self._cull_frequency == 0:

View File

@ -42,11 +42,11 @@ class ModPythonRequest(http.HttpRequest):
def is_secure(self): def is_secure(self):
# Note: modpython 3.2.10+ has req.is_https(), but we need to support previous versions # Note: modpython 3.2.10+ has req.is_https(), but we need to support previous versions
return self._req.subprocess_env.has_key('HTTPS') and self._req.subprocess_env['HTTPS'] == 'on' return 'HTTPS' in self._req.subprocess_env and self._req.subprocess_env['HTTPS'] == 'on'
def _load_post_and_files(self): def _load_post_and_files(self):
"Populates self._post and self._files" "Populates self._post and self._files"
if self._req.headers_in.has_key('content-type') and self._req.headers_in['content-type'].startswith('multipart'): if 'content-type' in self._req.headers_in and self._req.headers_in['content-type'].startswith('multipart'):
self._post, self._files = http.parse_file_upload(self._req.headers_in, self.raw_post_data) self._post, self._files = http.parse_file_upload(self._req.headers_in, self.raw_post_data)
else: else:
self._post, self._files = http.QueryDict(self.raw_post_data), datastructures.MultiValueDict() self._post, self._files = http.QueryDict(self.raw_post_data), datastructures.MultiValueDict()

View File

@ -103,7 +103,7 @@ class WSGIRequest(http.HttpRequest):
return '%s%s' % (self.path, self.environ.get('QUERY_STRING', '') and ('?' + self.environ.get('QUERY_STRING', '')) or '') return '%s%s' % (self.path, self.environ.get('QUERY_STRING', '') and ('?' + self.environ.get('QUERY_STRING', '')) or '')
def is_secure(self): def is_secure(self):
return self.environ.has_key('HTTPS') and self.environ['HTTPS'] == 'on' return 'HTTPS' in self.environ and self.environ['HTTPS'] == 'on'
def _load_post_and_files(self): def _load_post_and_files(self):
# Populates self._post and self._files # Populates self._post and self._files

View File

@ -356,7 +356,7 @@ def get_sql_delete(app):
# Drop the table now # Drop the table now
output.append('%s %s;' % (style.SQL_KEYWORD('DROP TABLE'), output.append('%s %s;' % (style.SQL_KEYWORD('DROP TABLE'),
style.SQL_TABLE(backend.quote_name(model._meta.db_table)))) style.SQL_TABLE(backend.quote_name(model._meta.db_table))))
if backend.supports_constraints and references_to_delete.has_key(model): if backend.supports_constraints and model in references_to_delete:
for rel_class, f in references_to_delete[model]: for rel_class, f in references_to_delete[model]:
table = rel_class._meta.db_table table = rel_class._meta.db_table
col = f.column col = f.column
@ -902,7 +902,7 @@ def inspectdb():
att_name += '_field' att_name += '_field'
comment_notes.append('Field renamed because it was a Python reserved word.') comment_notes.append('Field renamed because it was a Python reserved word.')
if relations.has_key(i): if i in relations:
rel_to = relations[i][1] == table_name and "'self'" or table2model(relations[i][1]) rel_to = relations[i][1] == table_name and "'self'" or table2model(relations[i][1])
field_type = 'ForeignKey(%s' % rel_to field_type = 'ForeignKey(%s' % rel_to
if att_name.endswith('_id'): if att_name.endswith('_id'):
@ -1609,7 +1609,7 @@ def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING, argv=None):
action = args[0] action = args[0]
except IndexError: except IndexError:
parser.print_usage_and_exit() parser.print_usage_and_exit()
if not action_mapping.has_key(action): if action not in action_mapping:
print_error("Your action, %r, was invalid." % action, argv[0]) print_error("Your action, %r, was invalid." % action, argv[0])
# Switch to English, because django-admin.py creates database content # Switch to English, because django-admin.py creates database content

View File

@ -208,15 +208,15 @@ def guess_scheme(environ):
else: else:
return 'http' return 'http'
_hoppish = { _hop_headers = {
'connection':1, 'keep-alive':1, 'proxy-authenticate':1, 'connection':1, 'keep-alive':1, 'proxy-authenticate':1,
'proxy-authorization':1, 'te':1, 'trailers':1, 'transfer-encoding':1, 'proxy-authorization':1, 'te':1, 'trailers':1, 'transfer-encoding':1,
'upgrade':1 'upgrade':1
}.has_key }
def is_hop_by_hop(header_name): def is_hop_by_hop(header_name):
"""Return true if 'header_name' is an HTTP/1.1 "Hop-by-Hop" header""" """Return true if 'header_name' is an HTTP/1.1 "Hop-by-Hop" header"""
return _hoppish(header_name.lower()) return header_name.lower() in _hop_headers
class ServerHandler(object): class ServerHandler(object):
"""Manage the invocation of a WSGI application""" """Manage the invocation of a WSGI application"""
@ -334,7 +334,7 @@ class ServerHandler(object):
Subclasses can extend this to add other defaults. Subclasses can extend this to add other defaults.
""" """
if not self.headers.has_key('Content-Length'): if 'Content-Length' not in self.headers:
self.set_content_length() self.set_content_length()
def start_response(self, status, headers,exc_info=None): def start_response(self, status, headers,exc_info=None):
@ -368,11 +368,11 @@ class ServerHandler(object):
if self.origin_server: if self.origin_server:
if self.client_is_modern(): if self.client_is_modern():
self._write('HTTP/%s %s\r\n' % (self.http_version,self.status)) self._write('HTTP/%s %s\r\n' % (self.http_version,self.status))
if not self.headers.has_key('Date'): if 'Date' not in self.headers:
self._write( self._write(
'Date: %s\r\n' % time.asctime(time.gmtime(time.time())) 'Date: %s\r\n' % time.asctime(time.gmtime(time.time()))
) )
if self.server_software and not self.headers.has_key('Server'): if self.server_software and 'Server' not in self.headers:
self._write('Server: %s\r\n' % self.server_software) self._write('Server: %s\r\n' % self.server_software)
else: else:
self._write('Status: %s\r\n' % self.status) self._write('Status: %s\r\n' % self.status)

View File

@ -102,6 +102,14 @@ class RegexURLPattern(object):
self.default_args = default_args or {} self.default_args = default_args or {}
self.name = name self.name = name
def add_prefix(self, prefix):
"""
Adds the prefix string to a string-based callback.
"""
if not prefix or not hasattr(self, '_callback_str'):
return
self._callback_str = prefix + '.' + self._callback_str
def resolve(self, path): def resolve(self, path):
match = self.regex.search(path) match = self.regex.search(path)
if match: if match:

View File

@ -284,7 +284,7 @@ class ValidateIfOtherFieldEquals(object):
self.always_test = True self.always_test = True
def __call__(self, field_data, all_data): def __call__(self, field_data, all_data):
if all_data.has_key(self.other_field) and all_data[self.other_field] == self.other_value: if self.other_field in all_data and all_data[self.other_field] == self.other_value:
for v in self.validator_list: for v in self.validator_list:
v(field_data, all_data) v(field_data, all_data)
@ -322,7 +322,7 @@ class RequiredIfOtherFieldEquals(object):
self.always_test = True self.always_test = True
def __call__(self, field_data, all_data): def __call__(self, field_data, all_data):
if all_data.has_key(self.other_field) and all_data[self.other_field] == self.other_value and not field_data: if self.other_field in all_data and all_data[self.other_field] == self.other_value and not field_data:
raise ValidationError(self.error_message) raise ValidationError(self.error_message)
class RequiredIfOtherFieldDoesNotEqual(object): class RequiredIfOtherFieldDoesNotEqual(object):
@ -335,7 +335,7 @@ class RequiredIfOtherFieldDoesNotEqual(object):
self.always_test = True self.always_test = True
def __call__(self, field_data, all_data): def __call__(self, field_data, all_data):
if all_data.has_key(self.other_field) and all_data[self.other_field] != self.other_value and not field_data: if self.other_field in all_data and all_data[self.other_field] != self.other_value and not field_data:
raise ValidationError(self.error_message) raise ValidationError(self.error_message)
class IsLessThanOtherField(object): class IsLessThanOtherField(object):

View File

@ -53,7 +53,7 @@ class MysqlDebugWrapper:
raise Database.Warning, "%s: %s" % (w, self.cursor.fetchall()) raise Database.Warning, "%s: %s" % (w, self.cursor.fetchall())
def __getattr__(self, attr): def __getattr__(self, attr):
if self.__dict__.has_key(attr): if attr in self.__dict__:
return self.__dict__[attr] return self.__dict__[attr]
else: else:
return getattr(self.cursor, attr) return getattr(self.cursor, attr)

View File

@ -48,7 +48,7 @@ class UnicodeCursorWrapper(object):
return self.cursor.executemany(sql, new_param_list) return self.cursor.executemany(sql, new_param_list)
def __getattr__(self, attr): def __getattr__(self, attr):
if self.__dict__.has_key(attr): if attr in self.__dict__:
return self.__dict__[attr] return self.__dict__[attr]
else: else:
return getattr(self.cursor, attr) return getattr(self.cursor, attr)

View File

@ -34,7 +34,7 @@ class CursorDebugWrapper(object):
}) })
def __getattr__(self, attr): def __getattr__(self, attr):
if self.__dict__.has_key(attr): if attr in self.__dict__:
return self.__dict__[attr] return self.__dict__[attr]
else: else:
return getattr(self.cursor, attr) return getattr(self.cursor, attr)

View File

@ -788,7 +788,7 @@ class SlugField(Field):
kwargs['maxlength'] = kwargs.get('maxlength', 50) kwargs['maxlength'] = kwargs.get('maxlength', 50)
kwargs.setdefault('validator_list', []).append(validators.isSlug) kwargs.setdefault('validator_list', []).append(validators.isSlug)
# Set db_index=True unless it's been set manually. # Set db_index=True unless it's been set manually.
if not kwargs.has_key('db_index'): if 'db_index' not in kwargs:
kwargs['db_index'] = True kwargs['db_index'] = True
Field.__init__(self, *args, **kwargs) Field.__init__(self, *args, **kwargs)

View File

@ -37,7 +37,7 @@ class GenericForeignKey(object):
def instance_pre_init(self, signal, sender, args, kwargs): def instance_pre_init(self, signal, sender, args, kwargs):
# Handle initalizing an object with the generic FK instaed of # Handle initalizing an object with the generic FK instaed of
# content-type/object-id fields. # content-type/object-id fields.
if kwargs.has_key(self.name): if self.name in kwargs:
value = kwargs.pop(self.name) value = kwargs.pop(self.name)
kwargs[self.ct_field] = self.get_content_type(value) kwargs[self.ct_field] = self.get_content_type(value)
kwargs[self.fk_field] = value._get_pk_val() kwargs[self.fk_field] = value._get_pk_val()

View File

@ -471,7 +471,7 @@ class ForeignKey(RelatedField, Field):
to_field = to_field or to._meta.pk.name to_field = to_field or to._meta.pk.name
kwargs['verbose_name'] = kwargs.get('verbose_name', '') kwargs['verbose_name'] = kwargs.get('verbose_name', '')
if kwargs.has_key('edit_inline_type'): if 'edit_inline_type' in kwargs:
import warnings import warnings
warnings.warn("edit_inline_type is deprecated. Use edit_inline instead.") warnings.warn("edit_inline_type is deprecated. Use edit_inline instead.")
kwargs['edit_inline'] = kwargs.pop('edit_inline_type') kwargs['edit_inline'] = kwargs.pop('edit_inline_type')
@ -564,7 +564,7 @@ class OneToOneField(RelatedField, IntegerField):
to_field = to_field or to._meta.pk.name to_field = to_field or to._meta.pk.name
kwargs['verbose_name'] = kwargs.get('verbose_name', '') kwargs['verbose_name'] = kwargs.get('verbose_name', '')
if kwargs.has_key('edit_inline_type'): if 'edit_inline_type' in kwargs:
import warnings import warnings
warnings.warn("edit_inline_type is deprecated. Use edit_inline instead.") warnings.warn("edit_inline_type is deprecated. Use edit_inline instead.")
kwargs['edit_inline'] = kwargs.pop('edit_inline_type') kwargs['edit_inline'] = kwargs.pop('edit_inline_type')

View File

@ -103,7 +103,7 @@ def register_models(app_label, *models):
# in the _app_models dictionary # in the _app_models dictionary
model_name = model._meta.object_name.lower() model_name = model._meta.object_name.lower()
model_dict = _app_models.setdefault(app_label, {}) model_dict = _app_models.setdefault(app_label, {})
if model_dict.has_key(model_name): if model_name in model_dict:
# The same model may be imported via different paths (e.g. # The same model may be imported via different paths (e.g.
# appname.models and project.appname.models). We use the source # appname.models and project.appname.models). We use the source
# filename as a means to detect identity. # filename as a means to detect identity.

View File

@ -145,7 +145,7 @@ class Options(object):
def get_follow(self, override=None): def get_follow(self, override=None):
follow = {} follow = {}
for f in self.fields + self.many_to_many + self.get_all_related_objects(): for f in self.fields + self.many_to_many + self.get_all_related_objects():
if override and override.has_key(f.name): if override and f.name in override:
child_override = override[f.name] child_override = override[f.name]
else: else:
child_override = None child_override = None
@ -187,7 +187,7 @@ class Options(object):
# TODO: follow # TODO: follow
if not hasattr(self, '_field_types'): if not hasattr(self, '_field_types'):
self._field_types = {} self._field_types = {}
if not self._field_types.has_key(field_type): if field_type not in self._field_types:
try: try:
# First check self.fields. # First check self.fields.
for f in self.fields: for f in self.fields:

View File

@ -46,12 +46,12 @@ def enter_transaction_management():
when no current block is running). when no current block is running).
""" """
thread_ident = thread.get_ident() thread_ident = thread.get_ident()
if state.has_key(thread_ident) and state[thread_ident]: if thread_ident in state and state[thread_ident]:
state[thread_ident].append(state[thread_ident][-1]) state[thread_ident].append(state[thread_ident][-1])
else: else:
state[thread_ident] = [] state[thread_ident] = []
state[thread_ident].append(settings.TRANSACTIONS_MANAGED) state[thread_ident].append(settings.TRANSACTIONS_MANAGED)
if not dirty.has_key(thread_ident): if thread_ident not in dirty:
dirty[thread_ident] = False dirty[thread_ident] = False
def leave_transaction_management(): def leave_transaction_management():
@ -61,7 +61,7 @@ def leave_transaction_management():
those from outside. (Commits are on connection level.) those from outside. (Commits are on connection level.)
""" """
thread_ident = thread.get_ident() thread_ident = thread.get_ident()
if state.has_key(thread_ident) and state[thread_ident]: if thread_ident in state and state[thread_ident]:
del state[thread_ident][-1] del state[thread_ident][-1]
else: else:
raise TransactionManagementError("This code isn't under transaction management") raise TransactionManagementError("This code isn't under transaction management")
@ -84,7 +84,7 @@ def set_dirty():
changes waiting for commit. changes waiting for commit.
""" """
thread_ident = thread.get_ident() thread_ident = thread.get_ident()
if dirty.has_key(thread_ident): if thread_ident in dirty:
dirty[thread_ident] = True dirty[thread_ident] = True
else: else:
raise TransactionManagementError("This code isn't under transaction management") raise TransactionManagementError("This code isn't under transaction management")
@ -96,7 +96,7 @@ def set_clean():
should happen. should happen.
""" """
thread_ident = thread.get_ident() thread_ident = thread.get_ident()
if dirty.has_key(thread_ident): if thread_ident in dirty:
dirty[thread_ident] = False dirty[thread_ident] = False
else: else:
raise TransactionManagementError("This code isn't under transaction management") raise TransactionManagementError("This code isn't under transaction management")
@ -106,7 +106,7 @@ def is_managed():
Checks whether the transaction manager is in manual or in auto state. Checks whether the transaction manager is in manual or in auto state.
""" """
thread_ident = thread.get_ident() thread_ident = thread.get_ident()
if state.has_key(thread_ident): if thread_ident in state:
if state[thread_ident]: if state[thread_ident]:
return state[thread_ident][-1] return state[thread_ident][-1]
return settings.TRANSACTIONS_MANAGED return settings.TRANSACTIONS_MANAGED

View File

@ -29,12 +29,12 @@ class HttpRequest(object):
def __getitem__(self, key): def __getitem__(self, key):
for d in (self.POST, self.GET): for d in (self.POST, self.GET):
if d.has_key(key): if key in d:
return d[key] return d[key]
raise KeyError, "%s not found in either POST or GET" % key raise KeyError, "%s not found in either POST or GET" % key
def has_key(self, key): def has_key(self, key):
return self.GET.has_key(key) or self.POST.has_key(key) return key in self.GET or key in self.POST
def get_full_path(self): def get_full_path(self):
return '' return ''
@ -57,7 +57,7 @@ def parse_file_upload(header_dict, post_data):
# name_dict is something like {'name': 'file', 'filename': 'test.txt'} for file uploads # name_dict is something like {'name': 'file', 'filename': 'test.txt'} for file uploads
# or {'name': 'blah'} for POST fields # or {'name': 'blah'} for POST fields
# We assume all uploaded files have a 'filename' set. # We assume all uploaded files have a 'filename' set.
if name_dict.has_key('filename'): if 'filename' in name_dict:
assert type([]) != type(submessage.get_payload()), "Nested MIME messages are not supported" assert type([]) != type(submessage.get_payload()), "Nested MIME messages are not supported"
if not name_dict['filename'].strip(): if not name_dict['filename'].strip():
continue continue
@ -66,7 +66,7 @@ def parse_file_upload(header_dict, post_data):
filename = name_dict['filename'][name_dict['filename'].rfind("\\")+1:] filename = name_dict['filename'][name_dict['filename'].rfind("\\")+1:]
FILES.appendlist(name_dict['name'], { FILES.appendlist(name_dict['name'], {
'filename': filename, 'filename': filename,
'content-type': (submessage.has_key('Content-Type') and submessage['Content-Type'] or None), 'content-type': 'Content-Type' in submessage and submessage['Content-Type'] or None,
'content': submessage.get_payload(), 'content': submessage.get_payload(),
}) })
else: else:

View File

@ -25,7 +25,7 @@ class CommonMiddleware(object):
""" """
# Check for denied User-Agents # Check for denied User-Agents
if request.META.has_key('HTTP_USER_AGENT'): if 'HTTP_USER_AGENT' in request.META:
for user_agent_regex in settings.DISALLOWED_USER_AGENTS: for user_agent_regex in settings.DISALLOWED_USER_AGENTS:
if user_agent_regex.search(request.META['HTTP_USER_AGENT']): if user_agent_regex.search(request.META['HTTP_USER_AGENT']):
return http.HttpResponseForbidden('<h1>Forbidden</h1>') return http.HttpResponseForbidden('<h1>Forbidden</h1>')

View File

@ -457,7 +457,7 @@ class MultiValueField(Field):
for i, field in enumerate(self.fields): for i, field in enumerate(self.fields):
try: try:
field_value = value[i] field_value = value[i]
except KeyError: except IndexError:
field_value = None field_value = None
if self.required and field_value in EMPTY_VALUES: if self.required and field_value in EMPTY_VALUES:
raise ValidationError(gettext(u'This field is required.')) raise ValidationError(gettext(u'This field is required.'))

View File

@ -244,7 +244,7 @@ class BoundField(StrAndUnicode):
def as_widget(self, widget, attrs=None): def as_widget(self, widget, attrs=None):
attrs = attrs or {} attrs = attrs or {}
auto_id = self.auto_id auto_id = self.auto_id
if auto_id and not attrs.has_key('id') and not widget.attrs.has_key('id'): if auto_id and 'id' not in attrs and 'id' not in widget.attrs:
attrs['id'] = auto_id attrs['id'] = auto_id
if not self.form.is_bound: if not self.form.is_bound:
data = self.form.initial.get(self.name, self.field.initial) data = self.form.initial.get(self.name, self.field.initial)

View File

@ -230,7 +230,7 @@ class RadioInput(StrAndUnicode):
return self.value == self.choice_value return self.value == self.choice_value
def tag(self): def tag(self):
if self.attrs.has_key('id'): if 'id' in self.attrs:
self.attrs['id'] = '%s_%s' % (self.attrs['id'], self.index) self.attrs['id'] = '%s_%s' % (self.attrs['id'], self.index)
final_attrs = dict(self.attrs, type='radio', name=self.name, value=self.choice_value) final_attrs = dict(self.attrs, type='radio', name=self.name, value=self.choice_value)
if self.is_checked(): if self.is_checked():
@ -276,7 +276,7 @@ class RadioSelect(Select):
class CheckboxSelectMultiple(SelectMultiple): class CheckboxSelectMultiple(SelectMultiple):
def render(self, name, value, attrs=None, choices=()): def render(self, name, value, attrs=None, choices=()):
if value is None: value = [] if value is None: value = []
has_id = attrs and attrs.has_key('id') has_id = attrs and 'id' in attrs
final_attrs = self.build_attrs(attrs, name=name) final_attrs = self.build_attrs(attrs, name=name)
output = [u'<ul>'] output = [u'<ul>']
str_values = set([smart_unicode(v) for v in value]) # Normalize to strings. str_values = set([smart_unicode(v) for v in value]) # Normalize to strings.
@ -347,7 +347,7 @@ class MultiWidget(Widget):
id_for_label = classmethod(id_for_label) 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 [widget.value_from_datadict(data, name + '_%s' % i) for i, widget in enumerate(self.widgets)]
def format_output(self, rendered_widgets): def format_output(self, rendered_widgets):
return u''.join(rendered_widgets) return u''.join(rendered_widgets)

View File

@ -329,7 +329,7 @@ class FormField(object):
def convert_post_data(self, new_data): def convert_post_data(self, new_data):
name = self.get_member_name() name = self.get_member_name()
if new_data.has_key(self.field_name): if self.field_name in new_data:
d = new_data.getlist(self.field_name) d = new_data.getlist(self.field_name)
try: try:
converted_data = [self.__class__.html2python(data) for data in d] converted_data = [self.__class__.html2python(data) for data in d]

View File

@ -338,7 +338,7 @@ class Parser(object):
return FilterExpression(token, self) return FilterExpression(token, self)
def find_filter(self, filter_name): def find_filter(self, filter_name):
if self.filters.has_key(filter_name): if filter_name in self.filters:
return self.filters[filter_name] return self.filters[filter_name]
else: else:
raise TemplateSyntaxError, "Invalid filter: '%s'" % filter_name raise TemplateSyntaxError, "Invalid filter: '%s'" % filter_name

View File

@ -35,7 +35,7 @@ class Context(object):
def __getitem__(self, key): def __getitem__(self, key):
"Get a variable's value, starting at the current context and going upward" "Get a variable's value, starting at the current context and going upward"
for d in self.dicts: for d in self.dicts:
if d.has_key(key): if key in d:
return d[key] return d[key]
raise KeyError(key) raise KeyError(key)
@ -45,7 +45,7 @@ class Context(object):
def has_key(self, key): def has_key(self, key):
for d in self.dicts: for d in self.dicts:
if d.has_key(key): if key in d:
return True return True
return False return False
@ -54,7 +54,7 @@ class Context(object):
def get(self, key, otherwise=None): def get(self, key, otherwise=None):
for d in self.dicts: for d in self.dicts:
if d.has_key(key): if key in d:
return d[key] return d[key]
return otherwise return otherwise

View File

@ -87,7 +87,7 @@ class ForNode(Node):
def render(self, context): def render(self, context):
nodelist = NodeList() nodelist = NodeList()
if context.has_key('forloop'): if 'forloop' in context:
parentloop = context['forloop'] parentloop = context['forloop']
else: else:
parentloop = {} parentloop = {}
@ -133,7 +133,7 @@ class IfChangedNode(Node):
self._varlist = varlist self._varlist = varlist
def render(self, context): def render(self, context):
if context.has_key('forloop') and context['forloop']['first']: if 'forloop' in context and context['forloop']['first']:
self._last_seen = None self._last_seen = None
try: try:
if self._varlist: if self._varlist:
@ -432,7 +432,7 @@ def cycle(parser, token):
name = args[1] name = args[1]
if not hasattr(parser, '_namedCycleNodes'): if not hasattr(parser, '_namedCycleNodes'):
raise TemplateSyntaxError("No named cycles in template: '%s' is not defined" % name) raise TemplateSyntaxError("No named cycles in template: '%s' is not defined" % name)
if not parser._namedCycleNodes.has_key(name): if name not in parser._namedCycleNodes:
raise TemplateSyntaxError("Named cycle '%s' does not exist" % name) raise TemplateSyntaxError("Named cycle '%s' does not exist" % name)
return parser._namedCycleNodes[name] return parser._namedCycleNodes[name]
@ -911,7 +911,7 @@ def templatetag(parser, token):
if len(bits) != 2: if len(bits) != 2:
raise TemplateSyntaxError, "'templatetag' statement takes one argument" raise TemplateSyntaxError, "'templatetag' statement takes one argument"
tag = bits[1] tag = bits[1]
if not TemplateTagNode.mapping.has_key(tag): if tag not in TemplateTagNode.mapping:
raise TemplateSyntaxError, "Invalid templatetag argument: '%s'. Must be one of: %s" % \ raise TemplateSyntaxError, "Invalid templatetag argument: '%s'. Must be one of: %s" % \
(tag, TemplateTagNode.mapping.keys()) (tag, TemplateTagNode.mapping.keys())
return TemplateTagNode(tag) return TemplateTagNode(tag)

View File

@ -42,7 +42,7 @@ class MergeDict(object):
def has_key(self, key): def has_key(self, key):
for dict in self.dicts: for dict in self.dicts:
if dict.has_key(key): if key in dict:
return True return True
return False return False

View File

@ -42,7 +42,7 @@ def lazy(func, *resultclasses):
res = self.__func(*self.__args, **self.__kw) res = self.__func(*self.__args, **self.__kw)
return self.__dispatch[type(res)][funcname](res, *args, **kw) return self.__dispatch[type(res)][funcname](res, *args, **kw)
if not self.__dispatch.has_key(klass): if klass not in self.__dispatch:
self.__dispatch[klass] = {} self.__dispatch[klass] = {}
self.__dispatch[klass][funcname] = func self.__dispatch[klass][funcname] = func
return __wrapper__ return __wrapper__

View File

@ -199,7 +199,7 @@ def deactivate():
will resolve against the default translation object, again. will resolve against the default translation object, again.
""" """
global _active global _active
if _active.has_key(currentThread()): if currentThread() in _active:
del _active[currentThread()] del _active[currentThread()]
def get_language(): def get_language():

View File

@ -97,7 +97,7 @@ def javascript_catalog(request, domain='djangojs', packages=None):
deliver your JavaScript source from Django templates. deliver your JavaScript source from Django templates.
""" """
if request.GET: if request.GET:
if request.GET.has_key('language'): if 'language' in request.GET:
if check_for_language(request.GET['language']): if check_for_language(request.GET['language']):
activate(request.GET['language']) activate(request.GET['language'])
if packages is None: if packages is None:
@ -136,7 +136,7 @@ def javascript_catalog(request, domain='djangojs', packages=None):
t.update(catalog._catalog) t.update(catalog._catalog)
src = [LibHead] src = [LibHead]
plural = None plural = None
if t.has_key(''): if '' in t:
for l in t[''].split('\n'): for l in t[''].split('\n'):
if l.startswith('Plural-Forms:'): if l.startswith('Plural-Forms:'):
plural = l.split(':',1)[1].strip() plural = l.split(':',1)[1].strip()
@ -155,7 +155,7 @@ def javascript_catalog(request, domain='djangojs', packages=None):
if type(k) in (str, unicode): if type(k) in (str, unicode):
csrc.append("catalog['%s'] = '%s';\n" % (javascript_quote(k), javascript_quote(v))) csrc.append("catalog['%s'] = '%s';\n" % (javascript_quote(k), javascript_quote(v)))
elif type(k) == tuple: elif type(k) == tuple:
if not pdict.has_key(k[0]): if k[0] not in pdict:
pdict[k[0]] = k[1] pdict[k[0]] = k[1]
else: else:
pdict[k[0]] = max(k[1], pdict[k[0]]) pdict[k[0]] = max(k[1], pdict[k[0]])

View File

@ -208,7 +208,8 @@ 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 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 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 only supported on platforms that have the standard Python ``crypt`` module
available. available, and ``crypt`` support is only available in the Django development
version.
For example:: For example::

View File

@ -45,16 +45,16 @@ Get your database running
========================= =========================
If you plan to use Django's database API functionality, you'll need to If you plan to use Django's database API functionality, you'll need to
make sure a database server is running. Django works with PostgreSQL_ make sure a database server is running. Django works with PostgreSQL_,
(recommended), MySQL_ and SQLite_. MySQL_ and SQLite_.
Additionally, you'll need to make sure your Python database bindings are Additionally, you'll need to make sure your Python database bindings are
installed. installed.
* If you're using PostgreSQL, you'll need the psycopg_ package (version 2 is * If you're using PostgreSQL, you'll need the psycopg_ package. Django supports
recommended with ``postgresql_psycopg2`` backend, version 1.1 works also with the both version 1 and 2. (When you configure Django's database layer, specify
``postgresql``` backend). either ``postgresql`` [for version 1] or ``postgresql_psycopg2`` [for version 2].)
If you're on Windows, check out the unofficial `compiled Windows version`_. If you're on Windows, check out the unofficial `compiled Windows version`_.
* If you're using MySQL, you'll need MySQLdb_, version 1.2.1p2 or higher. * If you're using MySQL, you'll need MySQLdb_, version 1.2.1p2 or higher.

View File

@ -562,9 +562,23 @@ 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_REDIRECT_URL
------------------
**New in Django development version**
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.
LOGIN_URL LOGIN_URL
--------- ---------
**New in Django development version**
Default: ``'/accounts/login/'`` Default: ``'/accounts/login/'``
The URL where requests are redirected for login, specially when using the The URL where requests are redirected for login, specially when using the
@ -573,6 +587,8 @@ The URL where requests are redirected for login, specially when using the
LOGOUT_URL LOGOUT_URL
---------- ----------
**New in Django development version**
Default: ``'/accounts/logout/'`` Default: ``'/accounts/logout/'``
LOGIN_URL counterpart. LOGIN_URL counterpart.
@ -635,16 +651,6 @@ 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
----------- -----------

View File

@ -55,8 +55,10 @@ class Tester(unittest.TestCase):
for t in self.ts: for t in self.ts:
if hasattr(t, 'x'): if hasattr(t, 'x'):
self.assert_(sd.has_key(safeRef(t.x))) self.assert_(sd.has_key(safeRef(t.x)))
self.assert_(safeRef(t.x) in sd)
else: else:
self.assert_(sd.has_key(safeRef(t))) self.assert_(sd.has_key(safeRef(t)))
self.assert_(safeRef(t) in sd)
def testRepresentation (self): def testRepresentation (self):
"""Test that the reference object's representation works """Test that the reference object's representation works

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,7 @@ from regressions import regression_tests
form_tests = r""" form_tests = r"""
>>> from django.newforms import * >>> from django.newforms import *
>>> import datetime >>> import datetime
>>> import time
>>> import re >>> import re
########### ###########
@ -3297,6 +3298,94 @@ True
<option value="2016">2016</option> <option value="2016">2016</option>
</select> </select>
# MultiWidget and MultiValueField #############################################
# MultiWidgets are widgets composed of other widgets. They are usually
# combined with MultiValueFields - a field that is composed of other fields.
# MulitWidgets can themselved be composed of other MultiWidgets.
# SplitDateTimeWidget is one example of a MultiWidget.
>>> class ComplexMultiWidget(MultiWidget):
... def __init__(self, attrs=None):
... widgets = (
... TextInput(),
... SelectMultiple(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))),
... SplitDateTimeWidget(),
... )
... super(ComplexMultiWidget, self).__init__(widgets, attrs)
...
... def decompress(self, value):
... if value:
... data = value.split(',')
... return [data[0], data[1], datetime.datetime(*time.strptime(data[2], "%Y-%m-%d %H:%M:%S")[0:6])]
... return [None, None, None]
... def format_output(self, rendered_widgets):
... return u'\n'.join(rendered_widgets)
>>> w = ComplexMultiWidget()
>>> print w.render('name', 'some text,JP,2007-04-25 06:24:00')
<input type="text" name="name_0" value="some text" />
<select multiple="multiple" name="name_1">
<option value="J" selected="selected">John</option>
<option value="P" selected="selected">Paul</option>
<option value="G">George</option>
<option value="R">Ringo</option>
</select>
<input type="text" name="name_2_0" value="2007-04-25" /><input type="text" name="name_2_1" value="06:24:00" />
>>> class ComplexField(MultiValueField):
... def __init__(self, required=True, widget=None, label=None, initial=None):
... fields = (
... CharField(),
... MultipleChoiceField(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))),
... SplitDateTimeField()
... )
... super(ComplexField, self).__init__(fields, required, widget, label, initial)
...
... def compress(self, data_list):
... if data_list:
... return '%s,%s,%s' % (data_list[0],''.join(data_list[1]),data_list[2])
... return None
>>> f = ComplexField(widget=w)
>>> f.clean(['some text', ['J','P'], ['2007-04-25','6:24:00']])
u'some text,JP,2007-04-25 06:24:00'
>>> f.clean(['some text',['X'], ['2007-04-25','6:24:00']])
Traceback (most recent call last):
...
ValidationError: [u'Select a valid choice. X is not one of the available choices.']
# If insufficient data is provided, None is substituted
>>> f.clean(['some text',['JP']])
Traceback (most recent call last):
...
ValidationError: [u'This field is required.']
>>> class ComplexFieldForm(Form):
... field1 = ComplexField(widget=w)
>>> f = ComplexFieldForm()
>>> print f
<tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" id="id_field1_0" />
<select multiple="multiple" name="field1_1" id="id_field1_1">
<option value="J">John</option>
<option value="P">Paul</option>
<option value="G">George</option>
<option value="R">Ringo</option>
</select>
<input type="text" name="field1_2_0" id="id_field1_2_0" /><input type="text" name="field1_2_1" id="id_field1_2_1" /></td></tr>
>>> f = ComplexFieldForm({'field1_0':'some text','field1_1':['J','P'], 'field1_2_0':'2007-04-25', 'field1_2_1':'06:24:00'})
>>> print f
<tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" value="some text" id="id_field1_0" />
<select multiple="multiple" name="field1_1" id="id_field1_1">
<option value="J" selected="selected">John</option>
<option value="P" selected="selected">Paul</option>
<option value="G">George</option>
<option value="R">Ringo</option>
</select>
<input type="text" name="field1_2_0" value="2007-04-25" id="id_field1_2_0" /><input type="text" name="field1_2_1" value="06:24:00" id="id_field1_2_1" /></td></tr>
>>> f.clean_data
{'field1': u'some text,JP,2007-04-25 06:24:00'}
################################# #################################
# Tests of underlying functions # # Tests of underlying functions #
################################# #################################

View File

@ -34,6 +34,9 @@ AttributeError: This QueryDict instance is immutable
>>> q.has_key('foo') >>> q.has_key('foo')
False False
>>> 'foo' in q
False
>>> q.items() >>> q.items()
[] []
@ -124,6 +127,9 @@ MultiValueDictKeyError: "Key 'foo' not found in <MultiValueDict: {}>"
>>> q.has_key('foo') >>> q.has_key('foo')
True True
>>> 'foo' in q
True
>>> q.items() >>> q.items()
[('foo', 'another'), ('name', 'john')] [('foo', 'another'), ('name', 'john')]
@ -218,9 +224,15 @@ AttributeError: This QueryDict instance is immutable
>>> q.has_key('foo') >>> q.has_key('foo')
True True
>>> 'foo' in q
True
>>> q.has_key('bar') >>> q.has_key('bar')
False False
>>> 'bar' in q
False
>>> q.items() >>> q.items()
[('foo', 'bar')] [('foo', 'bar')]
@ -303,9 +315,15 @@ AttributeError: This QueryDict instance is immutable
>>> q.has_key('vote') >>> q.has_key('vote')
True True
>>> 'vote' in q
True
>>> q.has_key('foo') >>> q.has_key('foo')
False False
>>> 'foo' in q
False
>>> q.items() >>> q.items()
[('vote', 'no')] [('vote', 'no')]