Changeset 7004
- Timestamp:
- 01/09/08 00:08:40 (9 months ago)
- Files:
-
- django/branches/queryset-refactor/django/contrib/admin/media/js/urlify.js (modified) (1 diff)
- django/branches/queryset-refactor/django/contrib/localflavor/ca/forms.py (modified) (1 diff)
- django/branches/queryset-refactor/django/contrib/sessions/backends/db.py (modified) (4 diffs)
- django/branches/queryset-refactor/django/contrib/sessions/backends/file.py (modified) (6 diffs)
- django/branches/queryset-refactor/django/core/mail.py (modified) (1 diff)
- django/branches/queryset-refactor/django/core/management/sql.py (modified) (1 diff)
- django/branches/queryset-refactor/django/db/backends/oracle/base.py (modified) (3 diffs)
- django/branches/queryset-refactor/django/template/context.py (modified) (3 diffs)
- django/branches/queryset-refactor/django/template/debug.py (added)
- django/branches/queryset-refactor/django/template/defaultfilters.py (modified) (3 diffs)
- django/branches/queryset-refactor/django/template/defaulttags.py (modified) (4 diffs)
- django/branches/queryset-refactor/django/template/__init__.py (modified) (24 diffs)
- django/branches/queryset-refactor/django/views/debug.py (modified) (1 diff)
- django/branches/queryset-refactor/docs/django-admin.txt (modified) (1 diff)
- django/branches/queryset-refactor/docs/localflavor.txt (modified) (1 diff)
- django/branches/queryset-refactor/docs/middleware.txt (modified) (1 diff)
- django/branches/queryset-refactor/docs/sites.txt (modified) (3 diffs)
- django/branches/queryset-refactor/docs/syndication_feeds.txt (modified) (1 diff)
- django/branches/queryset-refactor/docs/templates.txt (modified) (2 diffs)
- django/branches/queryset-refactor/tests/regressiontests/backends/models.py (modified) (2 diffs)
- django/branches/queryset-refactor/tests/regressiontests/forms/localflavor/ca.py (modified) (1 diff)
- django/branches/queryset-refactor/tests/regressiontests/middleware/models.py (added)
- django/branches/queryset-refactor/tests/regressiontests/middleware/tests.py (modified) (9 diffs)
- django/branches/queryset-refactor/tests/regressiontests/templates/filters.py (modified) (1 diff)
- django/branches/queryset-refactor/tests/regressiontests/templates/tests.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/queryset-refactor/django/contrib/admin/media/js/urlify.js
r6954 r7004 6 6 'Ý': 'Y', 'Þ': 'TH', 'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã': 'a', 'ä': 7 7 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e', 8 'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': ' o', 'ñ': 'n', 'ò': 'o', 'ó':8 'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 'o', 'ó': 9 9 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u', 10 10 'û': 'u', 'ü': 'u', 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y' django/branches/queryset-refactor/django/contrib/localflavor/ca/forms.py
r6954 r7004 81 81 Checks the following rules to determine whether the number is valid: 82 82 83 * Conforms to the XXX-XXX-XXX Xformat.83 * Conforms to the XXX-XXX-XXX format. 84 84 * Passes the check digit process "Luhn Algorithm" 85 85 See: http://en.wikipedia.org/wiki/Social_Insurance_Number 86 86 """ 87 87 default_error_messages = { 88 'invalid': ugettext('Enter a valid Canadian Social Insurance number in XXX-XXX-XXX Xformat.'),88 'invalid': ugettext('Enter a valid Canadian Social Insurance number in XXX-XXX-XXX format.'), 89 89 } 90 90 django/branches/queryset-refactor/django/contrib/sessions/backends/db.py
r6341 r7004 11 11 def __init__(self, session_key=None): 12 12 super(SessionStore, self).__init__(session_key) 13 13 14 14 def load(self): 15 15 try: 16 16 s = Session.objects.get( 17 session_key = self.session_key, 17 session_key = self.session_key, 18 18 expire_date__gt=datetime.datetime.now() 19 19 ) 20 20 return self.decode(s.session_data) 21 21 except (Session.DoesNotExist, SuspiciousOperation): 22 22 23 23 # Create a new session_key for extra security. 24 24 self.session_key = self._get_new_session_key() … … 27 27 # Save immediately to minimize collision 28 28 self.save() 29 # Ensure the user is notified via a new cookie. 30 self.modified = True 29 31 return {} 30 32 31 33 def exists(self, session_key): 32 34 try: … … 35 37 return False 36 38 return True 37 39 38 40 def save(self): 39 41 Session.objects.create( … … 42 44 expire_date = datetime.datetime.now() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE) 43 45 ) 44 46 45 47 def delete(self, session_key): 46 48 try: django/branches/queryset-refactor/django/contrib/sessions/backends/file.py
r6954 r7004 11 11 def __init__(self, session_key=None): 12 12 self.storage_path = getattr(settings, "SESSION_FILE_PATH", tempfile.gettempdir()) 13 13 14 14 # Make sure the storage path is valid. 15 15 if not os.path.isdir(self.storage_path): … … 18 18 "to an existing directory in which Django "\ 19 19 "can store session data." % self.storage_path) 20 21 self.file_prefix = settings.SESSION_COOKIE_NAME 20 21 self.file_prefix = settings.SESSION_COOKIE_NAME 22 22 super(SessionStore, self).__init__(session_key) 23 23 24 24 def _key_to_file(self, session_key=None): 25 25 """ … … 28 28 if session_key is None: 29 29 session_key = self.session_key 30 30 31 31 # Make sure we're not vulnerable to directory traversal. Session keys 32 32 # should always be md5s, so they should never contain directory components. 33 33 if os.path.sep in session_key: 34 34 raise SuspiciousOperation("Invalid characters (directory components) in session key") 35 35 36 36 return os.path.join(self.storage_path, self.file_prefix + session_key) 37 37 38 38 def load(self): 39 39 session_data = {} … … 47 47 self._session_cache = {} 48 48 self.save() 49 # Ensure the user is notified via a new cookie. 50 self.modified = True 49 51 finally: 50 52 session_file.close() … … 67 69 return True 68 70 return False 69 71 70 72 def delete(self, session_key): 71 73 try: … … 73 75 except OSError: 74 76 pass 75 77 76 78 def clean(self): 77 79 pass django/branches/queryset-refactor/django/core/mail.py
r6954 r7004 68 68 pass 69 69 70 def forbid_multi_line_headers(name, val): 71 "Forbids multi-line headers, to prevent header injection." 72 if '\n' in val or '\r' in val: 73 raise BadHeaderError("Header values can't contain newlines (got %r for header %r)" % (val, name)) 74 try: 75 val = force_unicode(val).encode('ascii') 76 except UnicodeEncodeError: 77 if name.lower() in ('to', 'from', 'cc'): 78 result = [] 79 for item in val.split(', '): 80 nm, addr = parseaddr(item) 81 nm = str(Header(nm, settings.DEFAULT_CHARSET)) 82 result.append(formataddr((nm, str(addr)))) 83 val = ', '.join(result) 84 else: 85 val = Header(force_unicode(val), settings.DEFAULT_CHARSET) 86 return name, val 87 70 88 class SafeMIMEText(MIMEText): 71 89 def __setitem__(self, name, val): 72 "Forbids multi-line headers, to prevent header injection." 73 if '\n' in val or '\r' in val: 74 raise BadHeaderError, "Header values can't contain newlines (got %r for header %r)" % (val, name) 75 try: 76 val = force_unicode(val).encode('ascii') 77 except UnicodeEncodeError: 78 if name.lower() in ('to', 'from', 'cc'): 79 result = [] 80 for item in val.split(', '): 81 nm, addr = parseaddr(item) 82 nm = str(Header(nm, settings.DEFAULT_CHARSET)) 83 result.append(formataddr((nm, str(addr)))) 84 val = ', '.join(result) 85 else: 86 val = Header(force_unicode(val), settings.DEFAULT_CHARSET) 90 name, val = forbid_multi_line_headers(name, val) 87 91 MIMEText.__setitem__(self, name, val) 88 92 89 93 class SafeMIMEMultipart(MIMEMultipart): 90 94 def __setitem__(self, name, val): 91 "Forbids multi-line headers, to prevent header injection." 92 if '\n' in val or '\r' in val: 93 raise BadHeaderError, "Header values can't contain newlines (got %r for header %r)" % (val, name) 94 try: 95 val = force_unicode(val).encode('ascii') 96 except UnicodeEncodeError: 97 if name.lower() in ('to', 'from', 'cc'): 98 result = [] 99 for item in val.split(', '): 100 nm, addr = parseaddr(item) 101 nm = str(Header(nm, settings.DEFAULT_CHARSET)) 102 result.append(formataddr((nm, str(addr)))) 103 val = ', '.join(result) 104 else: 105 val = Header(force_unicode(val), settings.DEFAULT_CHARSET) 95 name, val = forbid_multi_line_headers(name, val) 106 96 MIMEMultipart.__setitem__(self, name, val) 107 97 django/branches/queryset-refactor/django/core/management/sql.py
r6954 r7004 294 294 for field_constraints in opts.unique_together: 295 295 table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' % \ 296 ", ".join([ qn(style.SQL_FIELD(opts.get_field(f).column)) for f in field_constraints]))296 ", ".join([style.SQL_FIELD(qn(opts.get_field(f).column)) for f in field_constraints])) 297 297 298 298 full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + style.SQL_TABLE(qn(opts.db_table)) + ' ('] django/branches/queryset-refactor/django/db/backends/oracle/base.py
r6954 r7004 414 414 415 415 def _cursor(self, settings): 416 cursor = None 416 417 if not self._valid_connection(): 417 418 if len(settings.DATABASE_HOST.strip()) == 0: … … 423 424 conn_string = "%s/%s@%s" % (settings.DATABASE_USER, settings.DATABASE_PASSWORD, settings.DATABASE_NAME) 424 425 self.connection = Database.connect(conn_string, **self.options) 426 cursor = FormatStylePlaceholderCursor(self.connection) 427 # Set oracle date to ansi date format. This only needs to execute 428 # once when we create a new connection. 429 cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD' " 430 "NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'") 425 431 try: 426 432 self.oracle_version = int(self.connection.version.split('.')[0]) 427 433 except ValueError: 428 434 pass 429 cursor = FormatStylePlaceholderCursor(self.connection) 435 try: 436 self.connection.stmtcachesize = 20 437 except: 438 # Django docs specify cx_Oracle version 4.3.1 or higher, but 439 # stmtcachesize is available only in 4.3.2 and up. 440 pass 441 if not cursor: 442 cursor = FormatStylePlaceholderCursor(self.connection) 430 443 # Default arraysize of 1 is highly sub-optimal. 431 444 cursor.arraysize = 100 432 # Set oracle date to ansi date format.433 cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'")434 cursor.execute("ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'")435 445 return cursor 436 446 … … 507 517 508 518 def fetchone(self): 509 return to_unicode(Database.Cursor.fetchone(self)) 519 row = Database.Cursor.fetchone(self) 520 if row is None: 521 return row 522 return tuple([to_unicode(e) for e in row]) 510 523 511 524 def fetchmany(self, size=None): django/branches/queryset-refactor/django/template/context.py
r6857 r7004 10 10 class Context(object): 11 11 "A stack container for variable context" 12 13 12 def __init__(self, dict_=None, autoescape=True): 14 13 dict_ = dict_ or {} … … 79 78 mod = __import__(module, {}, {}, [attr]) 80 79 except ImportError, e: 81 raise ImproperlyConfigured , 'Error importing request processor module %s: "%s"' % (module, e)80 raise ImproperlyConfigured('Error importing request processor module %s: "%s"' % (module, e)) 82 81 try: 83 82 func = getattr(mod, attr) 84 83 except AttributeError: 85 raise ImproperlyConfigured , 'Module "%s" does not define a "%s" callable request processor' % (module, attr)84 raise ImproperlyConfigured('Module "%s" does not define a "%s" callable request processor' % (module, attr)) 86 85 processors.append(func) 87 86 _standard_context_processors = tuple(processors) … … 103 102 for processor in get_standard_processors() + processors: 104 103 self.update(processor(request)) 105 django/branches/queryset-refactor/django/template/defaultfilters.py
r6954 r7004 434 434 except IndexError: 435 435 return u'' 436 first.is_safe = True436 first.is_safe = False 437 437 438 438 def join(value, arg): … … 449 449 return data 450 450 join.is_safe = True 451 452 def last(value): 453 "Returns the last item in a list" 454 try: 455 return value[-1] 456 except IndexError: 457 return u'' 458 last.is_safe = True 451 459 452 460 def length(value): … … 801 809 register.filter(iriencode) 802 810 register.filter(join) 811 register.filter(last) 803 812 register.filter(length) 804 813 register.filter(length_is) django/branches/queryset-refactor/django/template/defaulttags.py
r6954 r7004 85 85 86 86 class ForNode(Node): 87 def __init__(self, loopvars, sequence, reversed, nodelist_loop):87 def __init__(self, loopvars, sequence, is_reversed, nodelist_loop): 88 88 self.loopvars, self.sequence = loopvars, sequence 89 self. reversed =reversed89 self.is_reversed = is_reversed 90 90 self.nodelist_loop = nodelist_loop 91 91 92 92 def __repr__(self): 93 if self.reversed: 94 reversed = ' reversed' 95 else: 96 reversed = '' 93 reversed_text = self.is_reversed and ' reversed' or '' 97 94 return "<For Node: for %s in %s, tail_len: %d%s>" % \ 98 95 (', '.join(self.loopvars), self.sequence, len(self.nodelist_loop), 99 reversed )96 reversed_text) 100 97 101 98 def __iter__(self): … … 126 123 values = list(values) 127 124 len_values = len(values) 128 if self. reversed:125 if self.is_reversed: 129 126 values = reversed(values) 130 127 unpack = len(self.loopvars) > 1 128 # Create a forloop value in the context. We'll update counters on each 129 # iteration just below. 130 loop_dict = context['forloop'] = {'parentloop': parentloop} 131 131 for i, item in enumerate(values): 132 context['forloop'] = { 133 # Shortcuts for current loop iteration number. 134 'counter0': i, 135 'counter': i+1, 136 # Reverse counter iteration numbers. 137 'revcounter': len_values - i, 138 'revcounter0': len_values - i - 1, 139 # Boolean values designating first and last times through loop. 140 'first': (i == 0), 141 'last': (i == len_values - 1), 142 'parentloop': parentloop, 143 } 132 # Shortcuts for current loop iteration number. 133 loop_dict['counter0'] = i 134 loop_dict['counter'] = i+1 135 # Reverse counter iteration numbers. 136 loop_dict['revcounter'] = len_values - i 137 loop_dict['revcounter0'] = len_values - i - 1 138 # Boolean values designating first and last times through loop. 139 loop_dict['first'] = (i == 0) 140 loop_dict['last'] = (i == len_values - 1) 141 144 142 if unpack: 145 143 # If there are multiple loop variables, unpack the item into … … 620 618 " words: %s" % token.contents) 621 619 622 reversed = bits[-1] == 'reversed'623 in_index = reversed and -3 or -2620 is_reversed = bits[-1] == 'reversed' 621 in_index = is_reversed and -3 or -2 624 622 if bits[in_index] != 'in': 625 623 raise TemplateSyntaxError("'for' statements should use the format" … … 635 633 nodelist_loop = parser.parse(('endfor',)) 636 634 parser.delete_first_token() 637 return ForNode(loopvars, sequence, reversed, nodelist_loop)635 return ForNode(loopvars, sequence, is_reversed, nodelist_loop) 638 636 do_for = register.tag("for", do_for) 639 637 django/branches/queryset-refactor/django/template/__init__.py
r6857 r7004 155 155 class Template(object): 156 156 def __init__(self, template_string, origin=None, name='<Unknown Template>'): 157 "Compilation stage"158 157 try: 159 158 template_string = smart_unicode(template_string) 160 159 except UnicodeDecodeError: 161 160 raise TemplateEncodingError("Templates can only be constructed from unicode or UTF-8 strings.") 162 if settings.TEMPLATE_DEBUG and origin ==None:161 if settings.TEMPLATE_DEBUG and origin is None: 163 162 origin = StringOrigin(template_string) 164 # Could do some crazy stack-frame stuff to record where this string165 # came from...166 163 self.nodelist = compile_string(template_string, origin) 167 164 self.name = name … … 178 175 def compile_string(template_string, origin): 179 176 "Compiles template_string into NodeList ready for rendering" 180 lexer = lexer_factory(template_string, origin) 181 parser = parser_factory(lexer.tokenize()) 177 if settings.TEMPLATE_DEBUG: 178 from debug import DebugLexer, DebugParser 179 lexer_class, parser_class = DebugLexer, DebugParser 180 else: 181 lexer_class, parser_class = Lexer, Parser 182 lexer = lexer_class(template_string, origin) 183 parser = parser_class(lexer.tokenize()) 182 184 return parser.parse() 183 185 184 186 class Token(object): 185 187 def __init__(self, token_type, contents): 186 "The token_type must be TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK or TOKEN_COMMENT"188 # token_type must be TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK or TOKEN_COMMENT. 187 189 self.token_type, self.contents = token_type, contents 188 190 … … 201 203 202 204 def tokenize(self): 203 "Return a list of tokens from a given template_string "205 "Return a list of tokens from a given template_string." 204 206 in_tag = False 205 207 result = [] … … 225 227 else: 226 228 token = Token(TOKEN_TEXT, token_string) 227 return token228 229 class DebugLexer(Lexer):230 def __init__(self, template_string, origin):231 super(DebugLexer, self).__init__(template_string, origin)232 233 def tokenize(self):234 "Return a list of tokens from a given template_string"235 result, upto = [], 0236 for match in tag_re.finditer(self.template_string):237 start, end = match.span()238 if start > upto:239 result.append(self.create_token(self.template_string[upto:start], (upto, start), False))240 upto = start241 result.append(self.create_token(self.template_string[start:end], (start, end), True))242 upto = end243 last_bit = self.template_string[upto:]244 if last_bit:245 result.append(self.create_token(last_bit, (upto, upto + len(last_bit)), False))246 return result247 248 def create_token(self, token_string, source, in_tag):249 token = super(DebugLexer, self).create_token(token_string, in_tag)250 token.source = self.origin, source251 229 return token 252 230 … … 320 298 pass 321 299 322 def error(self, token, msg ):300 def error(self, token, msg): 323 301 return TemplateSyntaxError(msg) 324 302 325 303 def empty_variable(self, token): 326 raise self.error( token, "Empty variable tag")304 raise self.error(token, "Empty variable tag") 327 305 328 306 def empty_block_tag(self, token): 329 raise self.error( token, "Empty block tag")307 raise self.error(token, "Empty block tag") 330 308 331 309 def invalid_block_tag(self, token, command): 332 raise self.error( token, "Invalid block tag: '%s'" % command)310 raise self.error(token, "Invalid block tag: '%s'" % command) 333 311 334 312 def unclosed_block_tag(self, parse_until): … … 359 337 return self.filters[filter_name] 360 338 else: 361 raise TemplateSyntaxError, "Invalid filter: '%s'" % filter_name 362 363 class DebugParser(Parser): 364 def __init__(self, lexer): 365 super(DebugParser, self).__init__(lexer) 366 self.command_stack = [] 367 368 def enter_command(self, command, token): 369 self.command_stack.append( (command, token.source) ) 370 371 def exit_command(self): 372 self.command_stack.pop() 373 374 def error(self, token, msg): 375 return self.source_error(token.source, msg) 376 377 def source_error(self, source,msg): 378 e = TemplateSyntaxError(msg) 379 e.source = source 380 return e 381 382 def create_nodelist(self): 383 return DebugNodeList() 384 385 def create_variable_node(self, contents): 386 return DebugVariableNode(contents) 387 388 def extend_nodelist(self, nodelist, node, token): 389 node.source = token.source 390 super(DebugParser, self).extend_nodelist(nodelist, node, token) 391 392 def unclosed_block_tag(self, parse_until): 393 command, source = self.command_stack.pop() 394 msg = "Unclosed tag '%s'. Looking for one of: %s " % (command, ', '.join(parse_until)) 395 raise self.source_error( source, msg) 396 397 def compile_function_error(self, token, e): 398 if not hasattr(e, 'source'): 399 e.source = token.source 400 401 def lexer_factory(*args, **kwargs): 402 if settings.TEMPLATE_DEBUG: 403 return DebugLexer(*args, **kwargs) 404 else: 405 return Lexer(*args, **kwargs) 406 407 def parser_factory(*args, **kwargs): 408 if settings.TEMPLATE_DEBUG: 409 return DebugParser(*args, **kwargs) 410 else: 411 return Parser(*args, **kwargs) 339 raise TemplateSyntaxError("Invalid filter: '%s'" % filter_name) 412 340 413 341 class TokenParser(object): … … 427 355 def top(self): 428 356 "Overload this method to do the actual parsing and return the result." 429 raise NotImplemented 357 raise NotImplementedError() 430 358 431 359 def more(self): … … 436 364 "Undoes the last microparser. Use this for lookahead and backtracking." 437 365 if not len(self.backout): 438 raise TemplateSyntaxError , "back called without some previous parsing"366 raise TemplateSyntaxError("back called without some previous parsing") 439 367 self.pointer = self.backout.pop() 440 368 … … 444 372 i = self.pointer 445 373 if i >= len(subject): 446 raise TemplateSyntaxError , "expected another tag, found end of string: %s" % subject374 raise TemplateSyntaxError("expected another tag, found end of string: %s" % subject) 447 375 p = i 448 376 while i < len(subject) and subject[i] not in (' ', '\t'): … … 460 388 i = self.pointer 461 389 if i >= len(subject): 462 raise TemplateSyntaxError , "Searching for value. Expected another value but found end of string: %s" % subject390 raise TemplateSyntaxError("Searching for value. Expected another value but found end of string: %s" % subject) 463 391 if subject[i] in ('"', "'"): 464 392 p = i … … 467 395 i += 1 468 396 if i >= len(subject): 469 raise TemplateSyntaxError , "Searching for value. Unexpected end of string in column %d: %s" % (i, subject)397 raise TemplateSyntaxError("Searching for value. Unexpected end of string in column %d: %s" % (i, subject)) 470 398 i += 1 471 399 res = subject[p:i] … … 484 412 i += 1 485 413 if i >= len(subject): 486 raise TemplateSyntaxError , "Searching for value. Unexpected end of string in column %d: %s" % (i, subject)414 raise TemplateSyntaxError("Searching for value. Unexpected end of string in column %d: %s" % (i, subject)) 487 415 i += 1 488 416 s = subject[p:i] … … 543 471 start = match.start() 544 472 if upto != start: 545 raise TemplateSyntaxError ,"Could not parse some characters: %s|%s|%s" % \546 (token[:upto], token[upto:start], token[start:]) 473 raise TemplateSyntaxError("Could not parse some characters: %s|%s|%s" % \ 474 (token[:upto], token[upto:start], token[start:])) 547 475 if var == None: 548 476 var, constant, i18n_constant = match.group("var", "constant", "i18n_constant") … … 553 481 upto = match.end() 554 482 if var == None: 555 raise TemplateSyntaxError , "Could not find variable at start of %s" % token483 raise TemplateSyntaxError("Could not find variable at start of %s" % token) 556 484 elif var.find(VARIABLE_ATTRIBUTE_SEPARATOR + '_') > -1 or var[0] == '_': 557 raise TemplateSyntaxError , "Variables and attributes may not begin with underscores: '%s'" % var485 raise TemplateSyntaxError("Variables and attributes may not begin with underscores: '%s'" % var) 558 486 else: 559 487 filter_name = match.group("filter_name") … … 571 499 upto = match.end() 572 500 if upto != len(token): 573 raise TemplateSyntaxError , "Could not parse the remainder: '%s' from '%s'" % (token[upto:], token)501 raise TemplateSyntaxError("Could not parse the remainder: '%s' from '%s'" % (token[upto:], token)) 574 502 self.filters = filters 575 503 self.var = Variable(var) … … 628 556 except IndexError: 629 557 # Not enough 630 raise TemplateSyntaxError , "%s requires %d arguments, %d provided" % (name, len(nondefs), plen)558 raise TemplateSyntaxError("%s requires %d arguments, %d provided" % (name, len(nondefs), plen)) 631 559 632 560 # Defaults can be overridden. … … 637 565 except IndexError: 638 566 # Too many. 639 raise TemplateSyntaxError , "%s requires %d arguments, %d provided" % (name, len(nondefs), plen)567 raise TemplateSyntaxError("%s requires %d arguments, %d provided" % (name, len(nondefs), plen)) 640 568 641 569 return True … … 817 745 return node.render(context) 818 746 819 class DebugNodeList(NodeList):820 def render_node(self, node, context):821 try:822 result = node.render(context)823 except TemplateSyntaxError, e:824 if not hasattr(e, 'source'):825 e.source = node.source826 raise827 except Exception, e:828 from sys import exc_info829 wrapped = TemplateSyntaxError('Caught an exception while rendering: %s' % e)830 wrapped.source = node.source831 wrapped.exc_info = exc_info()832 raise wrapped833 return result834 835 747 class TextNode(Node): 836 748 def __init__(self, s): … … 862 774 return force_unicode(output) 863 775 864 class DebugVariableNode(VariableNode):865 def render(self, context):866 try:867 output = force_unicode(self.filter_expression.resolve(context))868 except TemplateSyntaxError, e:869 if not hasattr(e, 'source'):870 e.source = self.source871 raise872 except UnicodeDecodeError:873 return ''874 if (context.autoescape and not isinstance(output, SafeData)) or isinstance(output, EscapeData):875 return escape(output)876 else:877 return output878 879 776 def generic_tag_compiler(params, defaults, name, node_class, parser, token): 880 777 "Returns a template.Node subclass." … … 888 785 else: 889 786 message = "%s takes between %s and %s arguments" % (name, bmin, bmax) 890 raise TemplateSyntaxError , message787 raise TemplateSyntaxError(message) 891 788 return node_class(bits) 892 789 … … 914 811 return compile_function 915 812 else: 916 raise InvalidTemplateLibrary , "Unsupported arguments to Library.tag: (%r, %r)", (name, compile_function)813 raise InvalidTemplateLibrary("Unsupported arguments to Library.tag: (%r, %r)", (name, compile_function)) 917 814 918 815 def tag_function(self,func): … … 938 835 return filter_func 939 836 else: 940 raise InvalidTemplateLibrary , "Unsupported arguments to Library.filter: (%r, %r)", (name, filter_func)837 raise InvalidTemplateLibrary("Unsupported arguments to Library.filter: (%r, %r)", (name, filter_func)) 941 838 942 839 def filter_function(self, func): … … 967 864 params = params[1:] 968 865 else: 969 raise TemplateSyntaxError , "Any tag function decorated with takes_context=True must have a first argument of 'context'"866 raise TemplateSyntaxError("Any tag function decorated with takes_context=True must have a first argument of 'context'") 970 867 971 868 class InclusionNode(Node): … … 1004 901 mod = __import__(module_name, {}, {}, ['']) 1005 902 except ImportError, e: 1006 raise InvalidTemplateLibrary , "Could not load template library from %s, %s" % (module_name, e)903 raise InvalidTemplateLibrary("Could not load template library from %s, %s" % (module_name, e)) 1007 904 try: 1008 905 lib = mod.register 1009 906 libraries[module_name] = lib 1010 907 except AttributeError: 1011 raise InvalidTemplateLibrary , "Template library %s does not have a variable named 'register'" % module_name908 raise InvalidTemplateLibrary("Template library %s does not have a variable named 'register'" % module_name) 1012 909 return lib 1013 910 django/branches/queryset-refactor/django/views/debug.py
r6954 r7004 508 508 </textarea> 509 509 <br><br> 510 <input type="submit" value="Share this traceback on public Web site">510 <input type="submit" value="Share this traceback on a public Web site"> 511 511 </div> 512 512 </form> django/branches/queryset-refactor/docs/django-admin.txt
r6954 r7004 717 717 variable. 718 718 719 Note that this option is unnecessary in ``manage.py``, because it takes care of720 setting ``DJANGO_SETTINGS_MODULE`` for you. 719 Note that this option is unnecessary in ``manage.py``, because it uses 720 ``settings.py`` from the current project by default. 721 721 722 722 Extra niceties django/branches/queryset-refactor/docs/localflavor.txt
r6954 r7004 182 182 183 183 A form field that validates input as a Canadian Social Insurance Number (SIN). 184 A valid number must have the format XXX-XXX-XXX Xand pass a `Luhn mod-10184 A valid number must have the format XXX-XXX-XXX and pass a `Luhn mod-10 185 185 checksum`_. 186 186 django/branches/queryset-refactor/docs/middleware.txt
r6954 r7004 154 154 155 155 .. _Authentication in Web requests: ../authentication/#authentication-in-web-requests 156 157 django.contrib.csrf.middleware.CsrfMiddleware 158 --------------------------------------------- 159 160 **New in Django development version** 161 162 Adds protection against Cross Site Request Forgeries by adding hidden form 163 fields to POST forms and checking requests for the correct value. See the 164 `Cross Site Request Forgery protection documentation`_. 165 166 .. _`Cross Site Request Forgery protection documentation`: ../csrf/ 156 167 157 168 django.middleware.transaction.TransactionMiddleware django/branches/queryset-refactor/docs/sites.txt
r6334 r7004 98 98 99 99 On a lower level, you can use the sites framework in your Django views to do 100 particular things based on whatsite in which the view is being called.100 particular things based on the site in which the view is being called. 101 101 For example:: 102 102 … … 331 331 332 332 * In the `syndication framework`_, the templates for ``title`` and 333 ``description`` automatically have access to a variable ``{{ { site }}}``,333 ``description`` automatically have access to a variable ``{{ site }}``, 334 334 which is the ``Site`` object representing the current site. Also, the 335 335 hook for providing item URLs will use the ``domain`` from the current … … 337 337 338 338 * In the `authentication framework`_, the ``django.contrib.auth.views.login`` 339 view passes the current ``Site`` name to the template as ``{{ { site_name }}}``.339 view passes the current ``Site`` name to the template as ``{{ site_name }}``. 340 340 <
