Changeset 8215 for django/branches/gis/django/core
- Timestamp:
- 08/05/08 12:15:33 (4 months ago)
- Files:
-
- django/branches/gis (modified) (1 prop)
- django/branches/gis/django/core/cache/backends/base.py (modified) (1 diff)
- django/branches/gis/django/core/cache/backends/filebased.py (modified) (8 diffs)
- django/branches/gis/django/core/cache/backends/locmem.py (modified) (1 diff)
- django/branches/gis/django/core/cache/__init__.py (modified) (4 diffs)
- django/branches/gis/django/core/files/temp.py (copied) (copied from django/trunk/django/core/files/temp.py)
- django/branches/gis/django/core/files/uploadedfile.py (modified) (2 diffs)
- django/branches/gis/django/core/files/uploadhandler.py (modified) (1 diff)
- django/branches/gis/django/core/handlers/base.py (modified) (6 diffs)
- django/branches/gis/django/core/handlers/modpython.py (modified) (5 diffs)
- django/branches/gis/django/core/handlers/wsgi.py (modified) (4 diffs)
- django/branches/gis/django/core/mail.py (modified) (3 diffs)
- django/branches/gis/django/core/management/commands/compilemessages.py (modified) (1 diff)
- django/branches/gis/django/core/management/commands/test.py (modified) (1 diff)
- django/branches/gis/django/core/management/commands/testserver.py (modified) (1 diff)
- django/branches/gis/django/core/management/sql.py (modified) (3 diffs)
- django/branches/gis/django/core/management/validation.py (modified) (2 diffs)
- django/branches/gis/django/core/paginator.py (modified) (5 diffs)
- django/branches/gis/django/core/serializers/base.py (modified) (1 diff)
- django/branches/gis/django/core/serializers/json.py (modified) (1 diff)
- django/branches/gis/django/core/serializers/pyyaml.py (modified) (1 diff)
- django/branches/gis/django/core/urlresolvers.py (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/gis
- Property svnmerge-integrated changed from /django/trunk:1-7978 to /django/trunk:1-8214
django/branches/gis/django/core/cache/backends/base.py
r6815 r8215 64 64 return self.get(key) is not None 65 65 66 __contains__ = has_key 66 def __contains__(self, key): 67 """ 68 Returns True if the key is in the cache and has not expired. 69 """ 70 # This is a separate method, rather than just a copy of has_key(), 71 # so that it always has the same functionality as has_key(), even 72 # if a subclass overrides it. 73 return self.has_key(key) django/branches/gis/django/core/cache/backends/filebased.py
r6920 r8215 1 1 "File-based cache backend" 2 2 3 import md54 import os,time3 import os 4 import time 5 5 try: 6 6 import cPickle as pickle 7 7 except ImportError: 8 8 import pickle 9 9 10 from django.core.cache.backends.base import BaseCache 11 from django.utils.hashcompat import md5_constructor 10 12 11 13 class CacheClass(BaseCache): 12 14 def __init__(self, dir, params): 13 15 BaseCache.__init__(self, params) 14 16 15 17 max_entries = params.get('max_entries', 300) 16 18 try: … … 18 20 except (ValueError, TypeError): 19 21 self._max_entries = 300 20 22 21 23 cull_frequency = params.get('cull_frequency', 3) 22 24 try: … … 24 26 except (ValueError, TypeError): 25 27 self._cull_frequency = 3 26 28 27 29 self._dir = dir 28 30 if not os.path.exists(self._dir): … … 32 34 if self.has_key(key): 33 35 return None 34 36 35 37 self.set(key, value, timeout) 36 38 … … 53 55 fname = self._key_to_file(key) 54 56 dirname = os.path.dirname(fname) 55 57 56 58 if timeout is None: 57 59 timeout = self.default_timeout 58 60 59 61 self._cull() 60 62 61 63 try: 62 64 if not os.path.exists(dirname): … … 104 106 if int(self._num_entries) < self._max_entries: 105 107 return 106 108 107 109 try: 108 110 filelist = os.listdir(self._dir) 109 111 except (IOError, OSError): 110 112 return 111 113 112 114 if self._cull_frequency == 0: 113 115 doomed = filelist … … 134 136 bits of the path into directory prefixes to be nice to filesystems 135 137 that have problems with large numbers of files in a directory. 136 138 137 139 Thus, a cache key of "foo" gets turnned into a file named 138 140 ``{cache-dir}ac/bd/18db4cc2f85cedef654fccc4a4d8``. 139 141 """ 140 path = md5 .new(key.encode('utf-8')).hexdigest()142 path = md5_constructor(key.encode('utf-8')).hexdigest() 141 143 path = os.path.join(path[:2], path[2:4], path[4:]) 142 144 return os.path.join(self._dir, path) … … 148 150 return count 149 151 _num_entries = property(_get_num_entries) 150 django/branches/gis/django/core/cache/backends/locmem.py
r6920 r8215 108 108 doomed = [k for (i, k) in enumerate(self._cache) if i % self._cull_frequency == 0] 109 109 for k in doomed: 110 self. delete(k)110 self._delete(k) 111 111 112 112 def _delete(self, key): django/branches/gis/django/core/cache/__init__.py
r6920 r8215 20 20 from django.core.cache.backends.base import InvalidCacheBackendError 21 21 22 # Name for use in settings file --> name of module in "backends" directory. 23 # Any backend scheme that is not in this dictionary is treated as a Python 24 # import path to a custom backend. 22 25 BACKENDS = { 23 # name for use in settings file --> name of module in "backends" directory24 26 'memcached': 'memcached', 25 27 'locmem': 'locmem', … … 27 29 'db': 'db', 28 30 'dummy': 'dummy', 29 }30 31 DEPRECATED_BACKENDS = {32 # deprecated backend --> replacement module33 'simple': 'locmem',34 31 } 35 32 … … 40 37 if not rest.startswith('//'): 41 38 raise InvalidCacheBackendError, "Backend URI must start with scheme://" 42 if scheme in DEPRECATED_BACKENDS:43 import warnings44 warnings.warn("'%s' backend is deprecated. Use '%s' instead." %45 (scheme, DEPRECATED_BACKENDS[scheme]), DeprecationWarning)46 scheme = DEPRECATED_BACKENDS[scheme]47 if scheme not in BACKENDS:48 raise InvalidCacheBackendError, "%r is not a valid cache backend" % scheme49 39 50 40 host = rest[2:] … … 58 48 host = host[:-1] 59 49 60 cache_class = getattr(__import__('django.core.cache.backends.%s' % BACKENDS[scheme], {}, {}, ['']), 'CacheClass') 61 return cache_class(host, params) 50 if scheme in BACKENDS: 51 module = __import__('django.core.cache.backends.%s' % BACKENDS[scheme], {}, {}, ['']) 52 else: 53 module = __import__(scheme, {}, {}, ['']) 54 return getattr(module, 'CacheClass')(host, params) 62 55 63 56 cache = get_cache(settings.CACHE_BACKEND) django/branches/gis/django/core/files/uploadedfile.py
r7918 r8215 4 4 5 5 import os 6 import tempfile7 6 import warnings 8 7 try: … … 12 11 13 12 from django.conf import settings 13 14 from django.core.files import temp as tempfile 14 15 15 16 __all__ = ('UploadedFile', 'TemporaryUploadedFile', 'InMemoryUploadedFile', 'SimpleUploadedFile') django/branches/gis/django/core/files/uploadhandler.py
r7918 r8215 2 2 Base file upload handler classes, and the built-in concrete subclasses 3 3 """ 4 import os 5 import tempfile 4 6 5 try: 7 6 from cStringIO import StringIO django/branches/gis/django/core/handlers/base.py
r7979 r8215 4 4 from django.core import signals 5 5 from django.dispatch import dispatcher 6 from django.utils.encoding import force_unicode 6 7 7 8 class BaseHandler(object): … … 74 75 resolver = urlresolvers.RegexURLResolver(r'^/', urlconf) 75 76 try: 76 callback, callback_args, callback_kwargs = resolver.resolve(request.path) 77 callback, callback_args, callback_kwargs = resolver.resolve( 78 request.path_info) 77 79 78 80 # Apply view middleware … … 108 110 return debug.technical_404_response(request, e) 109 111 else: 110 callback, param_dict = resolver.resolve404() 111 return callback(request, **param_dict) 112 try: 113 callback, param_dict = resolver.resolve404() 114 return callback(request, **param_dict) 115 except: 116 return self.handle_uncaught_exception(request, resolver, sys.exc_info()) 112 117 except exceptions.PermissionDenied: 113 118 return http.HttpResponseForbidden('<h1>Permission denied</h1>') … … 119 124 exc_info = sys.exc_info() 120 125 receivers = dispatcher.send(signal=signals.got_request_exception, request=request) 121 122 if settings.DEBUG_PROPAGATE_EXCEPTIONS:123 raise124 126 return self.handle_uncaught_exception(request, resolver, exc_info) 125 127 … … 136 138 from django.conf import settings 137 139 from django.core.mail import mail_admins 140 141 if settings.DEBUG_PROPAGATE_EXCEPTIONS: 142 raise 138 143 139 144 if settings.DEBUG: … … 168 173 return response 169 174 175 def get_script_name(environ): 176 """ 177 Returns the equivalent of the HTTP request's SCRIPT_NAME environment 178 variable. If Apache mod_rewrite has been used, returns what would have been 179 the script name prior to any rewriting (so it's the script name as seen 180 from the client's perspective), unless DJANGO_USE_POST_REWRITE is set (to 181 anything). 182 """ 183 from django.conf import settings 184 if settings.FORCE_SCRIPT_NAME is not None: 185 return force_unicode(settings.FORCE_SCRIPT_NAME) 186 187 # If Apache's mod_rewrite had a whack at the URL, Apache set either 188 # SCRIPT_URL or REDIRECT_URL to the full resource URL before applying any 189 # rewrites. Unfortunately not every webserver (lighttpd!) passes this 190 # information through all the time, so FORCE_SCRIPT_NAME, above, is still 191 # needed. 192 script_url = environ.get('SCRIPT_URL', u'') 193 if not script_url: 194 script_url = environ.get('REDIRECT_URL', u'') 195 if script_url: 196 return force_unicode(script_url[:-len(environ.get('PATH_INFO', ''))]) 197 return force_unicode(environ.get('SCRIPT_NAME', u'')) 198 django/branches/gis/django/core/handlers/modpython.py
r7836 r8215 5 5 from django.core import signals 6 6 from django.core.handlers.base import BaseHandler 7 from django.core.urlresolvers import set_script_prefix 7 8 from django.dispatch import dispatcher 8 9 from django.utils import datastructures … … 16 17 def __init__(self, req): 17 18 self._req = req 19 # FIXME: This isn't ideal. The request URI may be encoded (it's 20 # non-normalized) slightly differently to the "real" SCRIPT_NAME 21 # and PATH_INFO values. This causes problems when we compute path_info, 22 # below. For now, don't use script names that will be subject to 23 # encoding/decoding. 18 24 self.path = force_unicode(req.uri) 25 root = req.get_options().get('django.root', '') 26 self.django_root = root 27 # req.path_info isn't necessarily computed correctly in all 28 # circumstances (it's out of mod_python's control a bit), so we use 29 # req.uri and some string manipulations to get the right value. 30 if root and req.uri.startswith(root): 31 self.path_info = force_unicode(req.uri[len(root):]) 32 else: 33 self.path_info = self.path 34 if not self.path_info: 35 # Django prefers empty paths to be '/', rather than '', to give us 36 # a common start character for URL patterns. So this is a little 37 # naughty, but also pretty harmless. 38 self.path_info = u'/' 19 39 20 40 def __repr__(self): … … 101 121 'CONTENT_TYPE': self._req.content_type, # This may be wrong 102 122 'GATEWAY_INTERFACE': 'CGI/1.1', 103 'PATH_INFO': self. _req.path_info,123 'PATH_INFO': self.path_info, 104 124 'PATH_TRANSLATED': None, # Not supported 105 125 'QUERY_STRING': self._req.args, … … 109 129 'REMOTE_USER': self._req.user, 110 130 'REQUEST_METHOD': self._req.method, 111 'SCRIPT_NAME': None, # Not supported131 'SCRIPT_NAME': self.django_root, 112 132 'SERVER_NAME': self._req.server.server_hostname, 113 133 'SERVER_PORT': self._req.server.port, … … 154 174 self.load_middleware() 155 175 176 set_script_prefix(req.get_options().get('django.root', '')) 156 177 dispatcher.send(signal=signals.request_started) 157 178 try: django/branches/gis/django/core/handlers/wsgi.py
r7836 r8215 8 8 from django import http 9 9 from django.core import signals 10 from django.core.handlers.base import BaseHandler 10 from django.core.handlers import base 11 from django.core.urlresolvers import set_script_prefix 11 12 from django.dispatch import dispatcher 12 13 from django.utils import datastructures … … 75 76 class WSGIRequest(http.HttpRequest): 76 77 def __init__(self, environ): 78 script_name = base.get_script_name(environ) 79 path_info = force_unicode(environ.get('PATH_INFO', u'/')) 80 if not path_info: 81 # Sometimes PATH_INFO exists, but is empty (e.g. accessing 82 # the SCRIPT_NAME URL without a trailing slash). We really need to 83 # operate as if they'd requested '/'. Not amazingly nice to force 84 # the path like this, but should be harmless. 85 path_info = u'/' 77 86 self.environ = environ 78 self.path = force_unicode(environ['PATH_INFO']) 87 self.path_info = path_info 88 self.path = '%s%s' % (script_name, path_info) 79 89 self.META = environ 90 self.META['PATH_INFO'] = path_info 91 self.META['SCRIPT_NAME'] = script_name 80 92 self.method = environ['REQUEST_METHOD'].upper() 81 93 … … 179 191 raw_post_data = property(_get_raw_post_data) 180 192 181 class WSGIHandler( BaseHandler):193 class WSGIHandler(base.BaseHandler): 182 194 initLock = Lock() 183 195 request_class = WSGIRequest … … 195 207 self.initLock.release() 196 208 209 set_script_prefix(base.get_script_name(environ)) 197 210 dispatcher.send(signal=signals.request_started) 198 211 try: django/branches/gis/django/core/mail.py
r7918 r8215 72 72 def forbid_multi_line_headers(name, val): 73 73 """Forbids multi-line headers, to prevent header injection.""" 74 val = force_unicode(val) 74 75 if '\n' in val or '\r' in val: 75 76 raise BadHeaderError("Header values can't contain newlines (got %r for header %r)" % (val, name)) 76 77 try: 77 val = force_unicode(val).encode('ascii')78 val = val.encode('ascii') 78 79 except UnicodeEncodeError: 79 80 if name.lower() in ('to', 'from', 'cc'): … … 85 86 val = ', '.join(result) 86 87 else: 87 val = Header( force_unicode(val), settings.DEFAULT_CHARSET)88 val = Header(val, settings.DEFAULT_CHARSET) 88 89 return name, val 89 90 … … 175 176 def _send(self, email_message): 176 177 """A helper method that does the actual sending.""" 177 if not email_message. to:178 if not email_message.recipients(): 178 179 return False 179 180 try: django/branches/gis/django/core/management/commands/compilemessages.py
r7918 r8215 2 2 import sys 3 3 from optparse import make_option 4 from django.core.management.base import BaseCommand 5 from django.core.management.color import no_style 4 from django.core.management.base import BaseCommand, CommandError 6 5 7 6 try: django/branches/gis/django/core/management/commands/test.py
r7354 r8215 18 18 def handle(self, *test_labels, **options): 19 19 from django.conf import settings 20 from django.db.models import get_app, get_apps21 20 22 21 verbosity = int(options.get('verbosity', 1)) django/branches/gis/django/core/management/commands/testserver.py
r7354 r8215 18 18 19 19 def handle(self, *fixture_labels, **options): 20 from django.conf import settings21 20 from django.core.management import call_command 22 21 from django.test.utils import create_test_db django/branches/gis/django/core/management/sql.py
r7836 r8215 182 182 opts = model._meta 183 183 for f in opts.local_many_to_many: 184 if isinstance(f.rel, generic.GenericRel):184 if not f.creates_table: 185 185 continue 186 186 if cursor and table_name_converter(f.m2m_db_table()) in table_names: … … 354 354 inline_references = connection.features.inline_fk_references 355 355 for f in opts.local_many_to_many: 356 if not isinstance(f.rel, generic.GenericRel):356 if f.creates_table: 357 357 tablespace = f.db_tablespace or opts.db_tablespace 358 358 if tablespace and connection.features.supports_tablespaces: … … 436 436 437 437 # Post-creation SQL should come before any initial SQL data is loaded. 438 # However, this should not be done for fields that are part of a 439 # a parentmodel (via model inheritance).438 # However, this should not be done for fields that are part of a a parent 439 # model (via model inheritance). 440 440 nm = opts.init_name_map() 441 post_sql_fields = [f for f in opts. fields if nm[f.name][1] is None and hasattr(f, '_post_create_sql')]441 post_sql_fields = [f for f in opts.local_fields if hasattr(f, 'post_create_sql')] 442 442 for f in post_sql_fields: 443 output.extend(f. _post_create_sql(style, model._meta.db_table))443 output.extend(f.post_create_sql(style, model._meta.db_table)) 444 444 445 445 # Some backends can't execute more than one SQL statement at a time, django/branches/gis/django/core/management/validation.py
r7979 r8215 103 103 e.add(opts, "Reverse query name for field '%s' clashes with related field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name)) 104 104 105 seen_intermediary_signatures = [] 105 106 for i, f in enumerate(opts.local_many_to_many): 106 107 # Check to see if the related m2m field will clash with any … … 113 114 if isinstance(f.rel.to, (str, unicode)): 114 115 continue 115 116 if getattr(f.rel, 'through', None) is not None: 117 if hasattr(f.rel, 'through_model'): 118 from_model, to_model = cls, f.rel.to 119 if from_model == to_model and f.rel.symmetrical: 120 e.add(opts, "Many-to-many fields with intermediate tables cannot be symmetrical.") 121 seen_from, seen_to, seen_self = False, False, 0 122 for inter_field in f.rel.through_model._meta.fields: 123 rel_to = getattr(inter_field.rel, 'to', None) 124 if from_model == to_model: # relation to self 125 if rel_to == from_model: 126 seen_self += 1 127 if seen_self > 2: 128 e.add(opts, "Intermediary model %s has more than two foreign keys to %s, which is ambiguous and is not permitted." % (f.rel.through_model._meta.object_name, from_model._meta.object_name)) 129 else: 130 if rel_to == from_model: 131 if seen_from: 132 e.add(opts, "Intermediary model %s has more than one foreign key to %s, which is ambiguous and is not permitted." % (f.rel.through_model._meta.object_name, rel_from._meta.object_name)) 133 else: 134 seen_from = True 135 elif rel_to == to_model: 136 if seen_to: 137 e.add(opts, "Intermediary model %s has more than one foreign key to %s, which is ambiguous and is not permitted." % (f.rel.through_model._meta.object_name, rel_to._meta.object_name)) 138 else: 139 seen_to = True 140 if f.rel.through_model not in models.get_models(): 141 e.add(opts, "'%s' specifies an m2m relation through model %s, which has not been installed." % (f.name, f.rel.through)) 142 signature = (f.rel.to, cls, f.rel.through_model) 143 if signature in seen_intermediary_signatures: 144 e.add(opts, "The model %s has two manually-defined m2m relations through the model %s, which is not permitted. Please consider using an extra field on your intermediary model instead." % (cls._meta.object_name, f.rel.through_model._meta.object_name)) 145 else: 146 seen_intermediary_signatures.append(signature) 147 seen_related_fk, seen_this_fk = False, False 148 for field in f.rel.through_model._meta.fields: 149 if field.rel: 150 if not seen_related_fk and field.rel.to == f.rel.to: 151 seen_related_fk = True 152 elif field.rel.to == cls: 153 seen_this_fk = True 154 if not seen_related_fk or not seen_this_fk: 155 e.add(opts, "'%s' has a manually-defined m2m relation through model %s, which does not have foreign keys to %s and %s" % (f.name, f.rel.through, f.rel.to._meta.object_name, cls._meta.object_name)) 156 else: 157 e.add(opts, "'%s' specifies an m2m relation through model %s, which has not been installed" % (f.name, f.rel.through)) 158 116 159 rel_opts = f.rel.to._meta 117 160 rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name() django/branches/gis/django/core/paginator.py
r7918 r8215 1 from math import ceil 2 1 3 class InvalidPage(Exception): 2 4 pass … … 43 45 "Returns the total number of objects, across all pages." 44 46 if self._count is None: 45 from django.db.models.query import QuerySet 46 if isinstance(self.object_list, QuerySet): 47 try: 47 48 self._count = self.object_list.count() 48 else: 49 except (AttributeError, TypeError): 50 # AttributeError if object_list has no count() method. 51 # TypeError if object_list.count() requires arguments 52 # (i.e. is of type list). 49 53 self._count = len(self.object_list) 50 54 return self._count … … 54 58 "Returns the total number of pages." 55 59 if self._num_pages is None: 56 hits = self.count - 1 - self.orphans 57 if hits < 1: 58 hits = 0 59 if hits == 0 and not self.allow_empty_first_page: 60 if self.count == 0 and not self.allow_empty_first_page: 60 61 self._num_pages = 0 61 62 else: 62 self._num_pages = hits // self.per_page + 1 63 hits = max(1, self.count - self.orphans) 64 self._num_pages = int(ceil(hits / float(self.per_page))) 63 65 return self._num_pages 64 66 num_pages = property(_get_num_pages) … … 103 105 relative to total objects in the paginator. 104 106 """ 107 # Special case, return zero if no items. 108 if self.paginator.count == 0: 109 return 0 105 110 return (self.paginator.per_page * (self.number - 1)) + 1 106 111 … … 110 115 relative to total objects found (hits). 111 116 """ 117 # Special case for the last page because there can be orphans. 112 118 if self.number == self.paginator.num_pages: 113 119 return self.paginator.count 114 120 return self.number * self.paginator.per_page 115 116 class ObjectPaginator(Paginator):117 """118 Legacy ObjectPaginator class, for backwards compatibility.119 120 Note that each method on this class that takes page_number expects a121 zero-based page number, whereas the new API (Paginator/Page) uses one-based122 page numbers.123 """124 def __init__(self, query_set, num_per_page, orphans=0):125 Paginator.__init__(self, query_set, num_per_page, orphans)126 import warnings127 warnings.warn("The ObjectPaginator is deprecated. Use django.core.paginator.Paginator instead.", DeprecationWarning)128 129 # Keep these attributes around for backwards compatibility.130 self.query_set = query_set131 self.num_per_page = num_per_page132 self._hits = self._pages = None133 134 def validate_page_number(self, page_number):135 try:136 page_number = int(page_number) + 1137 except ValueError:138 raise PageNotAnInteger139 return self.validate_number(page_number)140 141 def get_page(self, page_number):142 try:143 page_number = int(page_number) + 1144 except ValueError:145 raise PageNotAnInteger146 return self.page(page_number).object_list147 148 def has_next_page(self, page_number):149 return page_number < self.pages - 1150 151 def has_previous_page(self, page_number):152 return page_number > 0153 154 def first_on_page(self, page_number):155 """156 Returns the 1-based index of the first object on the given page,157 relative to total objects found (hits).158 """159 page_number = self.validate_page_number(page_number)160 return (self.num_per_page * (page_number - 1)) + 1161 162 def last_on_page(self, page_number):163 """164 Returns the 1-based index of the last object on the given page,165 relative to total objects found (hits).166 """167 page_number = self.validate_page_number(page_number)168 if page_number == self.num_pages:169 return self.count170 return page_number * self.num_per_page171 172 def _get_count(self):173 # The old API allowed for self.object_list to be either a QuerySet or a174 # list. Here, we handle both.175 if self._count is None:176 try:177 self._count = self.object_list.count()178 except (AttributeError, TypeError):179 # AttributeError if object_list has no count() method.180 # TypeError if object_list.count() requires arguments181 # (i.e. is of type list).182 self._count = len(self.object_list)183 return self._count184 count = property(_get_count)185 186 # The old API called it "hits" instead of "count".187 hits = count188 189 # The old API called it "pages" instead of "num_pages".190 pages = Paginator.num_pagesdjango/branches/gis/django/core/serializers/base.py
r7979 r8215 3 3 """ 4 4 5 try: 6 from cStringIO import StringIO 7 except ImportError: 8 from StringIO import StringIO 5 from StringIO import StringIO 6 9 7 from django.db import models 10 8 from django.utils.encoding import smart_str, smart_unicode django/branches/gis/django/core/serializers/json.py
r7979 r8215 4 4 5 5 import datetime 6 from django.utils import simplejson 6 from StringIO import StringIO 7 7 8 from django.core.serializers.python import Serializer as PythonSerializer 8 9 from django.core.serializers.python import Deserializer as PythonDeserializer 9 10 from django.utils import datetime_safe 10 try: 11 from cStringIO import StringIO 12 except ImportError: 13 from StringIO import StringIO 11 from django.utils import simplejson 12 14 13 try: 15 14 import decimal django/branches/gis/django/core/serializers/pyyaml.py
r7176 r8215 5 5 """ 6 6 7 from StringIO import StringIO 8 import yaml 9 7 10 from django.db import models 8 11 from django.core.serializers.python import Serializer as PythonSerializer 9 12 from django.core.serializers.python import Deserializer as PythonDeserializer 10 try:11 from cStringIO import StringIO12 except ImportError:13 from StringIO import StringIO14 import yaml15 13 16 14 class Serializer(PythonSerializer): django/branches/gis/django/core/urlresolvers.py
r7836 r8215 7 7 (view_function, function_args, function_kwargs) 8 8 """ 9 10 import re 9 11 10 12 from django.http import Http404 … … 12 14 from django.utils.encoding import iri_to_uri, force_unicode, smart_str 13 15 from django.utils.functional import memoize 14 import re 16 from django.utils.thread_support import currentThread 15 17 16 18 try: … … 21 23 _resolver_cache = {} # Maps urlconf modules to RegexURLResolver instances. 22 24 _callable_cache = {} # Maps view and url pattern names to their view functions. 25 26 # SCRIPT_NAME prefixes for each thread are stored here. If there's no entry for 27 # the current thread (which is the only one we ever access), it is assumed to 28 # be empty. 29 _prefixes = {} 23 30 24 31 class Resolver404(Http404): … … 292 299 return get_resolver(urlconf).resolve(path) 293 300 294 def reverse(viewname, urlconf=None, args=None, kwargs=None ):301 def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None): 295 302 args = args or [] 296 303 kwargs = kwargs or {} 297 return iri_to_uri(u'/' + get_resolver(urlconf).reverse(viewname, *args, **kwargs)) 304 if prefix is None: 305 prefix = get_script_prefix() 306 return iri_to_uri(u'%s%s' % (prefix, get_resolver(urlconf).reverse(viewname, 307 *args, **kwargs))) 298 308 299 309 def clear_url_caches(): … … 302 312 _resolver_cache.clear() 303 313 _callable_cache.clear() 314 315 def set_script_prefix(prefix): 316 """ 317 Sets the script prefix for the current thread. 318 """ 319 if not prefix.endswith('/'): 320 prefix += '/' 321 _prefixes[currentThread()] = prefix 322 323 def get_script_prefix(): 324 """ 325 Returns the currently active script prefix. Useful for client code that 326 wishes to construct their own URLs manually (although accessing the request 327 instance is normally going to be a lot cleaner). 328 """ 329 return _prefixes.get(currentThread(), u'/') 330
