Changeset 4063
- Timestamp:
- 11/10/06 09:42:40 (2 years ago)
- Files:
-
- django/branches/generic-auth/django/conf/global_settings.py (modified) (2 diffs)
- django/branches/generic-auth/django/contrib/admin/media/js/dateparse.js (modified) (1 diff)
- django/branches/generic-auth/django/contrib/admin/templatetags/admin_modify.py (modified) (1 diff)
- django/branches/generic-auth/django/contrib/comments/models.py (modified) (1 diff)
- django/branches/generic-auth/django/core/mail.py (modified) (2 diffs)
- django/branches/generic-auth/django/core/management.py (modified) (1 diff)
- django/branches/generic-auth/django/core/paginator.py (modified) (5 diffs)
- django/branches/generic-auth/django/core/serializers/base.py (modified) (2 diffs)
- django/branches/generic-auth/django/core/serializers/python.py (modified) (1 diff)
- django/branches/generic-auth/django/core/serializers/xml_serializer.py (modified) (1 diff)
- django/branches/generic-auth/django/core/servers/fastcgi.py (modified) (2 diffs)
- django/branches/generic-auth/django/core/urlresolvers.py (modified) (1 diff)
- django/branches/generic-auth/django/core/validators.py (modified) (3 diffs)
- django/branches/generic-auth/django/db/backends/ado_mssql/base.py (modified) (1 diff)
- django/branches/generic-auth/django/db/backends/dummy/base.py (modified) (1 diff)
- django/branches/generic-auth/django/db/backends/mysql/base.py (modified) (2 diffs)
- django/branches/generic-auth/django/db/backends/oracle/base.py (modified) (2 diffs)
- django/branches/generic-auth/django/db/backends/postgresql/base.py (modified) (2 diffs)
- django/branches/generic-auth/django/db/backends/postgresql_psycopg2/base.py (modified) (2 diffs)
- django/branches/generic-auth/django/db/backends/sqlite3/base.py (modified) (1 diff)
- django/branches/generic-auth/django/db/backends/util.py (modified) (1 diff)
- django/branches/generic-auth/django/db/__init__.py (modified) (1 diff)
- django/branches/generic-auth/django/db/models/fields/__init__.py (modified) (1 diff)
- django/branches/generic-auth/django/db/models/manipulators.py (modified) (1 diff)
- django/branches/generic-auth/django/forms/__init__.py (modified) (1 diff)
- django/branches/generic-auth/django/newforms/fields.py (modified) (2 diffs)
- django/branches/generic-auth/django/template/defaultfilters.py (modified) (1 diff)
- django/branches/generic-auth/django/template/defaulttags.py (modified) (2 diffs)
- django/branches/generic-auth/django/template/__init__.py (modified) (1 diff)
- django/branches/generic-auth/docs/forms.txt (modified) (1 diff)
- django/branches/generic-auth/docs/settings.txt (modified) (2 diffs)
- django/branches/generic-auth/docs/syndication_feeds.txt (modified) (4 diffs)
- django/branches/generic-auth/docs/templates_python.txt (modified) (1 diff)
- django/branches/generic-auth/docs/templates.txt (modified) (3 diffs)
- django/branches/generic-auth/docs/testing.txt (modified) (1 diff)
- django/branches/generic-auth/tests/modeltests/pagination/models.py (modified) (1 diff)
- django/branches/generic-auth/tests/regressiontests/templates/tests.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/generic-auth/django/conf/global_settings.py
r4026 r4063 102 102 DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. 103 103 DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. 104 DATABASE_OPTIONS = {} # Set to empty dictionary for default. 104 105 105 106 # Host for sending e-mail. … … 229 230 TRANSACTIONS_MANAGED = False 230 231 232 # The User-Agent string to use when checking for URL validity through the 233 # isExistingURL validator. 234 URL_VALIDATOR_USER_AGENT = "Django/0.96pre (http://www.djangoproject.com)" 235 231 236 ############## 232 237 # MIDDLEWARE # django/branches/generic-auth/django/contrib/admin/media/js/dateparse.js
r2448 r4063 170 170 var d = new Date(); 171 171 d.setYear(parseInt(bits[1])); 172 d.setMonth(parseInt(bits[2], 10) - 1); 172 173 d.setDate(parseInt(bits[3], 10)); 173 d.setMonth(parseInt(bits[2], 10) - 1);174 174 return d; 175 175 } django/branches/generic-auth/django/contrib/admin/templatetags/admin_modify.py
r4026 r4063 178 178 179 179 def auto_populated_field_script(auto_pop_fields, change = False): 180 t = [] 180 181 for field in auto_pop_fields: 181 t = []182 182 if change: 183 183 t.append('document.getElementById("id_%s")._changed = true;' % field.name) django/branches/generic-auth/django/contrib/comments/models.py
r4024 r4063 35 35 Given a rating_string, this returns a tuple of (rating_range, options). 36 36 >>> s = "scale:1-10|First_category|Second_category" 37 >>> get_rating_options(s)37 >>> Comment.objects.get_rating_options(s) 38 38 ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ['First category', 'Second category']) 39 39 """ django/branches/generic-auth/django/core/mail.py
r2984 r4063 5 5 from email.Header import Header 6 6 import smtplib, rfc822 7 import socket 8 import time 9 import random 10 11 DNS_NAME = socket.getfqdn() # Cache the hostname 7 12 8 13 class BadHeaderError(ValueError): … … 52 57 msg['Date'] = rfc822.formatdate() 53 58 try: 59 random_bits = str(random.getrandbits(64)) 60 except AttributeError: # Python 2.3 doesn't have random.getrandbits(). 61 random_bits = ''.join([random.choice('1234567890') for i in range(19)]) 62 msg['Message-ID'] = "<%d.%d@%s>" % (time.time(), random_bits, DNS_NAME) 63 try: 54 64 server.sendmail(from_email, recipient_list, msg.as_string()) 55 65 num_sent += 1 django/branches/generic-auth/django/core/management.py
r4026 r4063 350 350 fp = open(sql_file, 'U') 351 351 for statement in statements.split(fp.read()): 352 # Remove any comments from the file 353 statement = re.sub(r"--.*[\n\Z]", "", statement) 352 354 if statement.strip(): 353 355 output.append(statement + ";") django/branches/generic-auth/django/core/paginator.py
r4024 r4063 1 from math import ceil2 3 1 class InvalidPage(Exception): 4 2 pass … … 6 4 class ObjectPaginator(object): 7 5 """ 8 This class makes pagination easy. Feed it a QuerySet , plus the number of9 o bjects you want on each page. Then read the hits and pages properties to6 This class makes pagination easy. Feed it a QuerySet or list, plus the number 7 of objects you want on each page. Then read the hits and pages properties to 10 8 see how many pages it involves. Call get_page with a page number (starting 11 9 at 0) to get back a list of objects for that page. … … 13 11 Finally, check if a page number has a next/prev page using 14 12 has_next_page(page_number) and has_previous_page(page_number). 13 14 Use orphans to avoid small final pages. For example: 15 13 records, num_per_page=10, orphans=2 --> pages==2, len(self.get_page(0))==10 16 12 records, num_per_page=10, orphans=2 --> pages==1, len(self.get_page(0))==12 15 17 """ 16 def __init__(self, query_set, num_per_page ):18 def __init__(self, query_set, num_per_page, orphans=0): 17 19 self.query_set = query_set 18 20 self.num_per_page = num_per_page 19 self. _hits, self._pages = None, None20 self._h as_next = {} # Caches page_number -> has_next_boolean21 self.orphans = orphans 22 self._hits = self._pages = None 21 23 22 def get_page(self, page_number):24 def validate_page_number(self, page_number): 23 25 try: 24 26 page_number = int(page_number) 25 27 except ValueError: 26 28 raise InvalidPage 27 if page_number < 0 :29 if page_number < 0 or page_number > self.pages - 1: 28 30 raise InvalidPage 31 return page_number 29 32 30 # Retrieve one extra record, and check for the existence of that extra 31 # record to determine whether there's a next page. 32 limit = self.num_per_page + 1 33 offset = page_number * self.num_per_page 34 35 object_list = list(self.query_set[offset:offset+limit]) 36 37 if not object_list: 38 raise InvalidPage 39 40 self._has_next[page_number] = (len(object_list) > self.num_per_page) 41 return object_list[:self.num_per_page] 33 def get_page(self, page_number): 34 page_number = self.validate_page_number(page_number) 35 bottom = page_number * self.num_per_page 36 top = bottom + self.num_per_page 37 if top + self.orphans >= self.hits: 38 top = self.hits 39 return self.query_set[bottom:top] 42 40 43 41 def has_next_page(self, page_number): 44 42 "Does page $page_number have a 'next' page?" 45 if not self._has_next.has_key(page_number): 46 if self._pages is None: 47 offset = (page_number + 1) * self.num_per_page 48 self._has_next[page_number] = len(self.query_set[offset:offset+1]) > 0 49 else: 50 self._has_next[page_number] = page_number < (self.pages - 1) 51 return self._has_next[page_number] 43 return page_number < self.pages - 1 52 44 53 45 def has_previous_page(self, page_number): … … 59 51 relative to total objects found (hits). 60 52 """ 61 if page_number == 0: 62 return 1 53 page_number = self.validate_page_number(page_number) 63 54 return (self.num_per_page * page_number) + 1 64 55 … … 68 59 relative to total objects found (hits). 69 60 """ 70 if page_number == 0 and self.num_per_page >= self._hits:71 return self._hits72 elif page_number == (self._pages - 1) and (page_number + 1) * self.num_per_page > self._hits:73 return self. _hits74 return (page_number + 1)* self.num_per_page61 page_number = self.validate_page_number(page_number) 62 page_number += 1 # 1-base 63 if page_number == self.pages: 64 return self.hits 65 return page_number * self.num_per_page 75 66 76 67 def _get_hits(self): 77 68 if self._hits is None: 78 self._hits = self.query_set.count() 69 # Try .count() or fall back to len(). 70 try: 71 self._hits = int(self.query_set.count()) 72 except (AttributeError, TypeError, ValueError): 73 # AttributeError if query_set has no object count. 74 # TypeError if query_set.count() required arguments. 75 # ValueError if int() fails. 76 self._hits = len(self.query_set) 79 77 return self._hits 80 78 81 79 def _get_pages(self): 82 80 if self._pages is None: 83 self._pages = int(ceil(self.hits / float(self.num_per_page))) 81 hits = (self.hits - 1 - self.orphans) 82 if hits < 1: 83 hits = 0 84 self._pages = hits // self.num_per_page + 1 84 85 return self._pages 85 86 django/branches/generic-auth/django/core/serializers/base.py
r4026 r4063 29 29 30 30 self.stream = options.get("stream", StringIO()) 31 self.selected_fields = options.get("fields") 31 32 32 33 self.start_serialization() … … 37 38 continue 38 39 elif field.rel is None: 39 self.handle_field(obj, field) 40 if self.selected_fields is None or field.attname in self.selected_fields: 41 self.handle_field(obj, field) 40 42 else: 41 self.handle_fk_field(obj, field) 43 if self.selected_fields is None or field.attname[:-3] in self.selected_fields: 44 self.handle_fk_field(obj, field) 42 45 for field in obj._meta.many_to_many: 43 self.handle_m2m_field(obj, field) 46 if self.selected_fields is None or field.attname in self.selected_fields: 47 self.handle_m2m_field(obj, field) 44 48 self.end_object(obj) 45 49 self.end_serialization() django/branches/generic-auth/django/core/serializers/python.py
r4024 r4063 77 77 78 78 # Handle FK fields 79 elif field.rel and isinstance(field.rel, models.ManyToOneRel) :79 elif field.rel and isinstance(field.rel, models.ManyToOneRel) and field_value is not None: 80 80 try: 81 81 data[field.name] = field.rel.to._default_manager.get(pk=field_value) django/branches/generic-auth/django/core/serializers/xml_serializer.py
r4024 r4063 167 167 # validation error, but that's expected). 168 168 RelatedModel = self._get_model_from_node(node, "to") 169 return RelatedModel.objects.get(pk=getInnerText(node).strip().encode(self.encoding)) 169 # Check if there is a child node named 'None', returning None if so. 170 if len(node.childNodes) == 1 and node.childNodes[0].nodeName == 'None': 171 return None 172 else: 173 return RelatedModel.objects.get(pk=getInnerText(node).strip().encode(self.encoding)) 170 174 171 175 def _handle_m2m_field_node(self, node): django/branches/generic-auth/django/core/servers/fastcgi.py
r4026 r4063 34 34 maxrequests=NUMBER number of requests a child handles before it is 35 35 killed and a new child is forked (0 = no limit). 36 maxspare=NUMBER max number of spare processes to keep running.37 minspare=NUMBER min number of spare processes to prefork.38 maxchildren=NUMBER hard limit number of processes in prefork mode.36 maxspare=NUMBER max number of spare processes / threads 37 minspare=NUMBER min number of spare processes / threads. 38 maxchildren=NUMBER hard limit number of processes / threads 39 39 daemonize=BOOL whether to detach from terminal. 40 40 pidfile=FILE write the spawned process-id to this file. … … 111 111 elif options['method'] in ('thread', 'threaded'): 112 112 from flup.server.fcgi import WSGIServer 113 wsgi_opts = {} 113 wsgi_opts = { 114 'maxSpare': int(options["maxspare"]), 115 'minSpare': int(options["minspare"]), 116 'maxThreads': int(options["maxchildren"]), 117 } 114 118 else: 115 119 return fastcgi_help("ERROR: Implementation must be one of prefork or thread.") django/branches/generic-auth/django/core/urlresolvers.py
r4026 r4063 22 22 # Converts 'django.views.news.stories.story_detail' to 23 23 # ['django.views.news.stories', 'story_detail'] 24 dot = callback.rindex('.') 24 try: 25 dot = callback.rindex('.') 26 except ValueError: 27 return callback, '' 25 28 return callback[:dot], callback[dot+1:] 26 29 django/branches/generic-auth/django/core/validators.py
r4026 r4063 9 9 """ 10 10 11 import urllib2 11 12 from django.conf import settings 12 13 from django.utils.translation import gettext, gettext_lazy, ngettext … … 224 225 225 226 def isExistingURL(field_data, all_data): 226 import urllib2 227 try: 228 u = urllib2.urlopen(field_data) 227 try: 228 headers = { 229 "Accept" : "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", 230 "Accept-Language" : "en-us,en;q=0.5", 231 "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", 232 "Connection" : "close", 233 "User-Agent": settings.URL_VALIDATOR_USER_AGENT 234 } 235 req = urllib2.Request(field_data,None, headers) 236 u = urllib2.urlopen(req) 229 237 except ValueError: 230 raise ValidationError, gettext("Invalid URL: %s") % field_data238 raise ValidationError, _("Invalid URL: %s") % field_data 231 239 except urllib2.HTTPError, e: 232 240 # 401s are valid; they just mean authorization is required. 233 if e.code not in ('401',): 234 raise ValidationError, gettext("The URL %s is a broken link.") % field_data 241 # 301 and 302 are redirects; they just mean look somewhere else. 242 if str(e.code) not in ('401','301','302'): 243 raise ValidationError, _("The URL %s is a broken link.") % field_data 235 244 except: # urllib2.URLError, httplib.InvalidURL, etc. 236 raise ValidationError, gettext("The URL %s is a broken link.") % field_data237 245 raise ValidationError, _("The URL %s is a broken link.") % field_data 246 238 247 def isValidUSState(field_data, all_data): 239 248 "Checks that the given string is a valid two-letter U.S. state abbreviation" … … 344 353 if field_name != self.field_name and value == field_data: 345 354 raise ValidationError, self.error_message 355 356 class NumberIsInRange(object): 357 """ 358 Validator that tests if a value is in a range (inclusive). 359 """ 360 def __init__(self, lower=None, upper=None, error_message=''): 361 self.lower, self.upper = lower, upper 362 if not error_message: 363 if lower and upper: 364 self.error_message = gettext("This value must be between %s and %s.") % (lower, upper) 365 elif lower: 366 self.error_message = gettext("This value must be at least %s.") % lower 367 elif upper: 368 self.error_message = gettext("This value must be no more than %s.") % upper 369 else: 370 self.error_message = error_message 371 372 def __call__(self, field_data, all_data): 373 # Try to make the value numeric. If this fails, we assume another 374 # validator will catch the problem. 375 try: 376 val = float(field_data) 377 except ValueError: 378 return 379 380 # Now validate 381 if self.lower and self.upper and (val < self.lower or val > self.upper): 382 raise ValidationError(self.error_message) 383 elif self.lower and val < self.lower: 384 raise ValidationError(self.error_message) 385 elif self.upper and val > self.upper: 386 raise ValidationError(self.error_message) 346 387 347 388 class IsAPowerOf(object): django/branches/generic-auth/django/db/backends/ado_mssql/base.py
r3115 r4063 56 56 57 57 class DatabaseWrapper(local): 58 def __init__(self ):58 def __init__(self, **kwargs): 59 59 self.connection = None 60 60 self.queries = [] django/branches/generic-auth/django/db/backends/dummy/base.py
r3073 r4063 21 21 _rollback = complain 22 22 23 def __init__(self, **kwargs): 24 pass 25 23 26 def close(self): 24 27 pass # close() django/branches/generic-auth/django/db/backends/mysql/base.py
r4026 r4063 66 66 67 67 class DatabaseWrapper(local): 68 def __init__(self ):68 def __init__(self, **kwargs): 69 69 self.connection = None 70 70 self.queries = [] 71 71 self.server_version = None 72 self.options = kwargs 72 73 73 74 def _valid_connection(self): … … 96 97 if settings.DATABASE_PORT: 97 98 kwargs['port'] = int(settings.DATABASE_PORT) 99 kwargs.update(self.options) 98 100 self.connection = Database.connect(**kwargs) 99 101 cursor = self.connection.cursor() django/branches/generic-auth/django/db/backends/oracle/base.py
r4024 r4063 22 22 23 23 class DatabaseWrapper(local): 24 def __init__(self ):24 def __init__(self, **kwargs): 25 25 self.connection = None 26 26 self.queries = [] 27 self.options = kwargs 27 28 28 29 def _valid_connection(self): … … 36 37 if len(settings.DATABASE_PORT.strip()) != 0: 37 38 dsn = Database.makedsn(settings.DATABASE_HOST, int(settings.DATABASE_PORT), settings.DATABASE_NAME) 38 self.connection = Database.connect(settings.DATABASE_USER, settings.DATABASE_PASSWORD, dsn )39 self.connection = Database.connect(settings.DATABASE_USER, settings.DATABASE_PASSWORD, dsn, **self.options) 39 40 else: 40 41 conn_string = "%s/%s@%s" % (settings.DATABASE_USER, settings.DATABASE_PASSWORD, settings.DATABASE_NAME) 41 self.connection = Database.connect(conn_string )42 self.connection = Database.connect(conn_string, **self.options) 42 43 return FormatStylePlaceholderCursor(self.connection) 43 44 django/branches/generic-auth/django/db/backends/postgresql/base.py
r3115 r4063 22 22 23 23 class DatabaseWrapper(local): 24 def __init__(self ):24 def __init__(self, **kwargs): 25 25 self.connection = None 26 26 self.queries = [] 27 self.options = kwargs 27 28 28 29 def cursor(self): … … 41 42 if settings.DATABASE_PORT: 42 43 conn_string += " port=%s" % settings.DATABASE_PORT 43 self.connection = Database.connect(conn_string )44 self.connection = Database.connect(conn_string, **self.options) 44 45 self.connection.set_isolation_level(1) # make transactions transparent to all cursors 45 46 cursor = self.connection.cursor() django/branches/generic-auth/django/db/backends/postgresql_psycopg2/base.py
r4026 r4063 22 22 23 23 class DatabaseWrapper(local): 24 def __init__(self ):24 def __init__(self, **kwargs): 25 25 self.connection = None 26 26 self.queries = [] 27 self.options = kwargs 27 28 28 29 def cursor(self): … … 41 42 if settings.DATABASE_PORT: 42 43 conn_string += " port=%s" % settings.DATABASE_PORT 43 self.connection = Database.connect(conn_string )44 self.connection = Database.connect(conn_string, **self.options) 44 45 self.connection.set_isolation_level(1) # make transactions transparent to all cursors 45 46 cursor = self.connection.cursor() django/branches/generic-auth/django/db/backends/sqlite3/base.py
r4026 r4063 43 43 44 44 class DatabaseWrapper(local): 45 def __init__(self ):45 def __init__(self, **kwargs): 46 46 self.connection = None 47 47 self.queries = [] 48 self.options = kwargs 48 49 49 50 def cursor(self): 50 51 from django.conf import settings 51 52 if self.connection is None: 52 self.connection = Database.connect(settings.DATABASE_NAME, 53 detect_types=Database.PARSE_DECLTYPES | Database.PARSE_COLNAMES) 54 53 kwargs = { 54 'database': settings.DATABASE_NAME, 55 'detect_types': Database.PARSE_DECLTYPES | Database.PARSE_COLNAMES, 56 } 57 kwargs.update(self.options) 58 self.connection = Database.connect(**kwargs) 55 59 # Register extract and date_trunc functions. 56 60 self.connection.create_function("django_extract", 2, _sqlite_extract) django/branches/generic-auth/django/db/backends/util.py
r4026 r4063 18 18 params = tuple(params) 19 19 self.db.queries.append({ 20 'sql': sql % tuple(params),20 'sql': sql % params, 21 21 'time': "%.3f" % (stop - start), 22 22 }) django/branches/generic-auth/django/db/__init__.py
r4026 r4063 28 28 runshell = lambda: __import__('django.db.backends.%s.client' % settings.DATABASE_ENGINE, {}, {}, ['']).runshell() 29 29 30 connection = backend.DatabaseWrapper( )30 connection = backend.DatabaseWrapper(**settings.DATABASE_OPTIONS) 31 31 DatabaseError = backend.DatabaseError 32 32 django/branches/generic-auth/django/db/models/fields/__init__.py
r4026 r4063 586 586 def isWithinMediaRoot(field_data, all_data): 587 587 f = os.path.abspath(os.path.join(settings.MEDIA_ROOT, field_data)) 588 if not f.startswith(os.path. normpath(settings.MEDIA_ROOT)):588 if not f.startswith(os.path.abspath(os.path.normpath(settings.MEDIA_ROOT))): 589 589 raise validators.ValidationError, _("Enter a valid filename.") 590 590 field_list[1].validator_list.append(isWithinMediaRoot) django/branches/generic-auth/django/db/models/manipulators.py
r4026 r4063 287 287 # form fields, e.g. DateTime. 288 288 # This validation needs to occur after html2python to be effective. 289 field_val = all_data.get(f. attname, None)289 field_val = all_data.get(f.name, None) 290 290 if field_val is None: 291 291 # This will be caught by another validator, assuming the field django/branches/generic-auth/django/forms/__init__.py
r4026 r4063 109 109 prepopulated data and validation error messages to the formfield objects. 110 110 """ 111 def __init__(self, manipulator, data, error_dict, edit_inline=True): 112 self.manipulator, self.data = manipulator, data 111 def __init__(self, manipulator, data=None, error_dict=None, edit_inline=True): 112 self.manipulator = manipulator 113 if data is None: 114 data = {} 115 if error_dict is None: 116 error_dict = {} 117 self.data = data 113 118 self.error_dict = error_dict 114 119 self._inline_collections = None django/branches/generic-auth/django/newforms/fields.py
r4026 r4063 189 189 r'(?:/?|/\S+)$', re.IGNORECASE) 190 190 191 try: 192 from django.conf import settings 193 URL_VALIDATOR_USER_AGENT = settings.URL_VALIDATOR_USER_AGENT 194 except ImportError: 195 # It's OK if Django settings aren't configured. 196 URL_VALIDATOR_USER_AGENT = 'Django (http://www.djangoproject.com/)' 197 191 198 class URLField(RegexField): 192 def __init__(self, required=True, verify_exists=False, widget=None): 199 def __init__(self, required=True, verify_exists=False, widget=None, 200 validator_user_agent=URL_VALIDATOR_USER_AGENT): 193 201 RegexField.__init__(self, url_re, u'Enter a valid URL.', required, widget) 194 202 self.verify_exists = verify_exists 203 self.user_agent = validator_user_agent 195 204 196 205 def clean(self, value): … … 198 207 if self.verify_exists: 199 208 import urllib2 209 from django.conf import settings 210 headers = { 211 "Accept": "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", 212 "Accept-Language": "en-us,en;q=0.5", 213 "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", 214 "Connection": "close", 215 "User-Agent": self.user_agent, 216 } 200 217 try: 201 u = urllib2.urlopen(value) 218 req = urllib2.Request(value, None, headers) 219 u = urllib2.urlopen(req) 202 220 except ValueError: 203 221 raise ValidationError(u'Enter a valid URL.') django/branches/generic-auth/django/template/defaultfilters.py
r4026 r4063 422 422 bytes, etc). 423 423 """ 424 bytes = float(bytes) 424 try: 425 bytes = float(bytes) 426 except TypeError: 427 return "0 bytes" 428 425 429 if bytes < 1024: 426 430 return "%d byte%s" % (bytes, bytes != 1 and 's' or '') django/branches/generic-auth/django/template/defaulttags.py
r4026 r4063 125 125 126 126 class IfChangedNode(Node): 127 def __init__(self, nodelist ):127 def __init__(self, nodelist, *varlist): 128 128 self.nodelist = nodelist 129 129 self._last_seen = None 130 self._varlist = varlist 130 131 131 132 def render(self, context): 132 133 if context.has_key('forloop') and context['forloop']['first']: 133 134 self._last_seen = None 134 content = self.nodelist.render(context) 135 if content != self._last_seen: 135 try: 136 if self._varlist: 137 # Consider multiple parameters. 138 # This automatically behaves like a OR evaluation of the multiple variables. 139 compare_to = [resolve_variable(var, context) for var in self._varlist] 140 else: 141 compare_to = self.nodelist.render(context) 142 except VariableDoesNotExist: 143 compare_to = None 144 145 if compare_to != self._last_seen: 136 146 firstloop = (self._last_seen == None) 137 self._last_seen = co ntent147 self._last_seen = compare_to 138 148 context.push() 139 149 context['ifchanged'] = {'firstloop': firstloop} … … 635 645 Check if a value has changed from the last iteration of a loop. 636 646 637 The 'ifchanged' block tag is used within a loop. It checks its own rendered 638 contents against its previous state and only displays its content if the 639 value has changed:: 640 641 <h1>Archive for {{ year }}</h1> 642 643 {% for date in days %} 644 {% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %} 645 <a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a> 646 {% endfor %} 647 The 'ifchanged' block tag is used within a loop. It has two possible uses. 648 649 1. Checks its own rendered contents against its previous state and only 650 displays the content if it has changed. For example, this displays a list of 651 days, only displaying the month if it changes:: 652 653 <h1>Archive for {{ year }}</h1> 654 655 {% for date in days %} 656 {% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %} 657 <a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a> 658 {% endfor %} 659 660 2. If given a variable, check whether that variable has changed. For example, the 661 following shows the date every time it changes, but only shows the hour if both 662 the hour and the date have changed:: 663 664 {% for date in days %} 665 {% ifchanged date.date %} {{ date.date }} {% endifchanged %} 666 {% ifchanged date.hour date.date %} 667 {{ date.hour }} 668 {% endifchanged %} 669 {% endfor %} 647 670 """ 648 671 bits = token.contents.split() 649 if len(bits) != 1:650 raise TemplateSyntaxError, "'ifchanged' tag takes no arguments"651 672 nodelist = parser.parse(('endifchanged',)) 652 673 parser.delete_first_token() 653 return IfChangedNode(nodelist )674 return IfChangedNode(nodelist, *bits[1:]) 654 675 ifchanged = register.tag(ifchanged) 655 676 django/branches/generic-auth/django/template/__init__.py
r4026 r4063 869 869 870 870 if not getattr(self, 'nodelist', False): 871 from django.template.loader import get_template 872 t = get_template(file_name) 871 from django.template.loader import get_template, select_template 872 if hasattr(file_name, '__iter__'): 873 t = select_template(file_name) 874 else: 875 t = get_template(file_name) 873 876 self.nodelist = t
