Changeset 4151
- Timestamp:
- 12/04/06 12:04:55 (2 years ago)
- Files:
-
- django/branches/multiple-db-support/AUTHORS (modified) (4 diffs)
- django/branches/multiple-db-support/django/bin/daily_cleanup.py (modified) (2 diffs)
- django/branches/multiple-db-support/django/contrib/admin/templates/admin_doc/view_detail.html (modified) (1 diff)
- django/branches/multiple-db-support/django/contrib/auth/create_superuser.py (modified) (1 diff)
- django/branches/multiple-db-support/django/contrib/auth/forms.py (modified) (1 diff)
- django/branches/multiple-db-support/django/contrib/sitemaps/templates/sitemap_index.xml (modified) (1 diff)
- django/branches/multiple-db-support/django/contrib/sitemaps/templates/sitemap.xml (modified) (2 diffs)
- django/branches/multiple-db-support/django/core/handlers/base.py (modified) (3 diffs)
- django/branches/multiple-db-support/django/core/handlers/modpython.py (modified) (2 diffs)
- django/branches/multiple-db-support/django/core/handlers/wsgi.py (modified) (2 diffs)
- django/branches/multiple-db-support/django/core/management.py (modified) (3 diffs)
- django/branches/multiple-db-support/django/db/backends/mysql/base.py (modified) (4 diffs)
- django/branches/multiple-db-support/django/db/models/fields/__init__.py (modified) (3 diffs)
- django/branches/multiple-db-support/django/db/models/manipulators.py (modified) (3 diffs)
- django/branches/multiple-db-support/django/middleware/common.py (modified) (3 diffs)
- django/branches/multiple-db-support/django/template/__init__.py (modified) (1 diff)
- django/branches/multiple-db-support/django/test/client.py (modified) (15 diffs)
- django/branches/multiple-db-support/django/utils/itercompat.py (copied) (copied from django/trunk/django/utils/itercompat.py)
- django/branches/multiple-db-support/docs/faq.txt (modified) (1 diff)
- django/branches/multiple-db-support/docs/templates_python.txt (modified) (1 diff)
- django/branches/multiple-db-support/tests/regressiontests/dateformat/tests.py (modified) (4 diffs)
- django/branches/multiple-db-support/tests/regressiontests/templates/tests.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/multiple-db-support/AUTHORS
r4142 r4151 65 65 crankycoder@gmail.com 66 66 Matt Croydon <http://www.postneo.com/> 67 dackze+django@gmail.com 67 68 Jonathan Daugherty (cygnus) <http://www.cprogrammer.org/> 68 69 Jason Davies (Esaj) <http://www.jasondavies.com/> … … 105 106 Jeong-Min Lee 106 107 Christopher Lenz <http://www.cmlenz.net/> 108 lerouxb@gmail.com 107 109 limodou 110 mattmcc 108 111 Martin Maney <http://www.chipy.org/Martin_Maney> 109 112 Manuzhai … … 117 120 Robin Munn <http://www.geekforgod.com/> 118 121 Nebojša Dorđević 122 Fraser Nevett <mail@nevett.org> 119 123 Sam Newman <http://www.magpiebrain.com/> 120 124 Neal Norwitz <nnorwitz@google.com> … … 144 148 Swaroop C H <http://www.swaroopch.info> 145 149 Aaron Swartz <http://www.aaronsw.com/> 150 Tyson Tate <tyson@fallingbullets.com> 146 151 Tom Tobin 147 152 Tom Insam django/branches/multiple-db-support/django/bin/daily_cleanup.py
r2809 r4151 1 "Daily cleanup file" 1 """ 2 Daily cleanup job. 3 4 Can be run as a cronjob to clean out old data from the database (only expired 5 sessions at the moment). 6 """ 2 7 3 8 from django.db import backend, connection, transaction 4 5 DOCUMENTATION_DIRECTORY = '/home/html/documentation/'6 9 7 10 def clean_up(): … … 9 12 cursor = connection.cursor() 10 13 cursor.execute("DELETE FROM %s WHERE %s < NOW()" % \ 11 (backend.quote_name('core_sessions'), backend.quote_name('expire_date'))) 12 cursor.execute("DELETE FROM %s WHERE %s < NOW() - INTERVAL '1 week'" % \ 13 (backend.quote_name('registration_challenges'), backend.quote_name('request_date'))) 14 (backend.quote_name('django_session'), backend.quote_name('expire_date'))) 14 15 transaction.commit_unless_managed() 15 16 django/branches/multiple-db-support/django/contrib/admin/templates/admin_doc/view_detail.html
r3355 r4151 9 9 <h1>{{ name }}</h1> 10 10 11 <h2 class="subhead">{{ summary |escape}}</h2>11 <h2 class="subhead">{{ summary }}</h2> 12 12 13 13 <p>{{ body }}</p> django/branches/multiple-db-support/django/contrib/auth/create_superuser.py
r2841 r4151 47 47 sys.stderr.write("Error: That username is invalid. Use only letters, digits and underscores.\n") 48 48 username = None 49 continue 49 50 try: 50 51 User.objects.get(username=username) django/branches/multiple-db-support/django/contrib/auth/forms.py
r4142 r4151 5 5 from django.core import validators 6 6 from django import forms 7 from django.utils.translation import gettext_lazy as _8 7 9 8 class UserCreationForm(forms.Manipulator): django/branches/multiple-db-support/django/contrib/sitemaps/templates/sitemap_index.xml
r3712 r4151 1 1 <?xml version="1.0" encoding="UTF-8"?> 2 2 <sitemapindex xmlns="http://www.google.com/schemas/sitemap/0.84"> 3 {% for location in sitemaps %} 4 <sitemap> 5 <loc>{{ location|escape }}</loc> 6 </sitemap> 7 {% endfor %} 3 {% for location in sitemaps %}<sitemap><loc>{{ location|escape }}</loc></sitemap>{% endfor %} 8 4 </sitemapindex> django/branches/multiple-db-support/django/contrib/sitemaps/templates/sitemap.xml
r3712 r4151 1 1 <?xml version="1.0" encoding="UTF-8"?> 2 2 <urlset xmlns="http://www.google.com/schemas/sitemap/0.84"> 3 {% spaceless %} 3 4 {% for url in urlset %} 4 5 <url> … … 9 10 </url> 10 11 {% endfor %} 12 {% endspaceless %} 11 13 </urlset> django/branches/multiple-db-support/django/core/handlers/base.py
r3427 r4151 49 49 self._exception_middleware.insert(0, mw_instance.process_exception) 50 50 51 def get_response(self, path,request):51 def get_response(self, request): 52 52 "Returns an HttpResponse object for the given HttpRequest" 53 53 from django.core import exceptions, urlresolvers … … 63 63 resolver = urlresolvers.RegexURLResolver(r'^/', settings.ROOT_URLCONF) 64 64 try: 65 callback, callback_args, callback_kwargs = resolver.resolve( path)65 callback, callback_args, callback_kwargs = resolver.resolve(request.path) 66 66 67 67 # Apply view middleware … … 106 106 receivers = dispatcher.send(signal=signals.got_request_exception) 107 107 # When DEBUG is False, send an error message to the admins. 108 subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), getattr(request, 'path', ''))108 subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), request.path) 109 109 try: 110 110 request_repr = repr(request) django/branches/multiple-db-support/django/core/handlers/modpython.py
r4141 r4151 103 103 'SCRIPT_NAME': None, # Not supported 104 104 'SERVER_NAME': self._req.server.server_hostname, 105 'SERVER_PORT': s elf._req.server.port,105 'SERVER_PORT': str(self._req.connection.local_addr[1]), 106 106 'SERVER_PROTOCOL': self._req.protocol, 107 107 'SERVER_SOFTWARE': 'mod_python' … … 151 151 try: 152 152 request = ModPythonRequest(req) 153 response = self.get_response(req .uri, request)153 response = self.get_response(request) 154 154 155 155 # Apply response middleware django/branches/multiple-db-support/django/core/handlers/wsgi.py
r4141 r4151 75 75 self.environ = environ 76 76 self.path = environ['PATH_INFO'] 77 self.META = environ 77 self.META = environ 78 78 self.method = environ['REQUEST_METHOD'].upper() 79 79 … … 187 187 try: 188 188 request = WSGIRequest(environ) 189 response = self.get_response(request .path, request)189 response = self.get_response(request) 190 190 191 191 # Apply response middleware django/branches/multiple-db-support/django/core/management.py
r4142 r4151 670 670 Returns number of errors. 671 671 """ 672 from django.db import models, model_connection_name 672 from django.conf import settings 673 from django.db import connections, models, model_connection_name 673 674 from django.db.models.loading import get_app_errors 674 675 from django.db.models.fields.related import RelatedObject … … 682 683 opts = cls._meta 683 684 connection_name = model_connection_name(cls) 685 connection = connections[connection_name] 684 686 685 687 # Do field-specific validation. … … 712 714 if f.db_index not in (None, True, False): 713 715 e.add(opts, '"%s": "db_index" should be either None, True or False.' % f.name) 716 717 # Check that maxlength <= 255 if using older MySQL versions. 718 if settings.DATABASE_ENGINE == 'mysql': 719 db_version = connection.connection.get_server_version() 720 if db_version < (5, 0, 3) and isinstance(f, (models.CharField, models.CommaSeparatedIntegerField, models.SlugField)) and f.maxlength > 255: 721 e.add(opts, '"%s": %s cannot have a "maxlength" greater than 255 when you are using a version of MySQL prior to 5.0.3 (you are using %s).' % (f.name, f.__class__.__name__, '.'.join([str(n) for n in db_version[:3]]))) 714 722 715 723 # Check to see if the related field will clash with any django/branches/multiple-db-support/django/db/backends/mysql/base.py
r4127 r4151 14 14 from MySQLdb.constants import FIELD_TYPE 15 15 import types 16 import re 16 17 17 18 DatabaseError = Database.DatabaseError … … 24 25 FIELD_TYPE.TIME: util.typecast_time, 25 26 }) 27 28 # This should match the numerical portion of the version numbers (we can treat 29 # versions like 5.0.24 and 5.0.24a as the same). Based on the list of version 30 # at http://dev.mysql.com/doc/refman/4.1/en/news.html and 31 # http://dev.mysql.com/doc/refman/5.0/en/news.html . 32 server_version_re = re.compile(r'(\d{1,2})\.(\d{1,2})\.(\d{1,2})') 26 33 27 34 # This is an extra debug layer over MySQL queries, to display warnings. … … 57 64 self.connection = None 58 65 self.queries = [] 66 self.server_version = None 59 67 60 68 def _valid_connection(self): … … 106 114 self.connection.close() 107 115 self.connection = None 116 117 def get_server_version(self): 118 if not self.server_version: 119 if not self._valid_connection(): 120 self.cursor() 121 m = server_version_re.match(self.connection.get_server_info()) 122 if not m: 123 raise Exception('Unable to determine MySQL version from version string %r' % self.connection.get_server_info()) 124 self.server_version = tuple([int(x) for x in m.groups()]) 125 return self.server_version 108 126 109 127 supports_constraints = True django/branches/multiple-db-support/django/db/models/fields/__init__.py
r4142 r4151 6 6 from django.core.exceptions import ObjectDoesNotExist 7 7 from django.utils.functional import curry 8 from django.utils.itercompat import tee 8 9 from django.utils.text import capfirst 9 10 from django.utils.translation import gettext, gettext_lazy … … 81 82 self.unique_for_date, self.unique_for_month = unique_for_date, unique_for_month 82 83 self.unique_for_year = unique_for_year 83 self. choices = choices or []84 self._choices = choices or [] 84 85 self.radio_admin = radio_admin 85 86 self.help_text = help_text … … 324 325 def bind(self, fieldmapping, original, bound_field_class): 325 326 return bound_field_class(self, fieldmapping, original) 327 328 def _get_choices(self): 329 if hasattr(self._choices, 'next'): 330 choices, self._choices = tee(self._choices) 331 return choices 332 else: 333 return self._choices 334 choices = property(_get_choices) 326 335 327 336 class AutoField(Field): django/branches/multiple-db-support/django/db/models/manipulators.py
r4142 r4151 178 178 179 179 if f == related.field: 180 param = getattr(new_object, related.field.rel. field_name)180 param = getattr(new_object, related.field.rel.get_related_field().attname) 181 181 elif (not self.change) and isinstance(f, AutoField): 182 182 param = None … … 216 216 for f in related.opts.many_to_many: 217 217 if child_follow.get(f.name, None) and not f.rel.edit_inline: 218 setattr(new_rel_obj, f.name, f.rel.to.objects.filter(pk__in=rel_new_data[f.attname])) 218 new_value = rel_new_data[f.attname] 219 if f.rel.raw_id_admin: 220 new_value = new_value[0] 221 setattr(new_rel_obj, f.name, f.rel.to.objects.filter(pk__in=new_value)) 219 222 if self.change: 220 223 self.fields_changed.append('%s for %s "%s"' % (f.verbose_name, related.opts.verbose_name, new_rel_obj)) … … 301 304 else: 302 305 raise validators.ValidationError, _("%(object)s with this %(type)s already exists for the given %(field)s.") % \ 303 {'object': capfirst(opts.verbose_name), 'type': field_list[0].verbose_name, 'field': get_text_list( field_name_list[1:], 'and')}306 {'object': capfirst(opts.verbose_name), 'type': field_list[0].verbose_name, 'field': get_text_list([f.verbose_name for f in field_list[1:]], 'and')} 304 307 305 308 def manipulator_validator_unique_for_date(from_field, date_field, opts, lookup_type, self, field_data, all_data): django/branches/multiple-db-support/django/middleware/common.py
r4142 r4151 3 3 from django.core.mail import mail_managers 4 4 import md5 5 import re 5 6 6 7 class CommonMiddleware(object): … … 62 63 domain = http.get_host(request) 63 64 referer = request.META.get('HTTP_REFERER', None) 64 is_internal = referer and (domain inreferer)65 is_internal = _is_internal_request(domain, referer) 65 66 path = request.get_full_path() 66 67 if referer and not _is_ignorable_404(path) and (is_internal or '?' not in referer): … … 89 90 return True 90 91 return False 92 93 def _is_internal_request(domain, referer): 94 "Return true if the referring URL is the same domain as the current request" 95 # Different subdomains are treated as different domains. 96 return referer is not None and re.match("^https?://%s/" % re.escape(domain), referer) django/branches/multiple-db-support/django/template/__init__.py
r3739 r4151 533 533 if i18n_arg: 534 534 args.append((False, _(i18n_arg.replace(r'\"', '"')))) 535 elif constant_arg :535 elif constant_arg is not None: 536 536 args.append((False, constant_arg.replace(r'\"', '"'))) 537 537 elif var_arg: django/branches/multiple-db-support/django/test/client.py
r3739 r4151 9 9 class ClientHandler(BaseHandler): 10 10 """ 11 A HTTP Handler that can be used for testing purposes. 11 A HTTP Handler that can be used for testing purposes. 12 12 Uses the WSGI interface to compose requests, but returns 13 13 the raw HttpResponse object … … 25 25 try: 26 26 request = WSGIRequest(environ) 27 response = self.get_response(request .path, request)27 response = self.get_response(request) 28 28 29 29 # Apply response middleware … … 33 33 finally: 34 34 dispatcher.send(signal=signals.request_finished) 35 35 36 36 return response 37 37 … … 45 45 A simple method for encoding multipart POST data from a dictionary of 46 46 form values. 47 47 48 48 The key will be used as the form data name; the value will be transmitted 49 49 as content. If the value is a file, the contents of the file will be sent … … 70 70 str(value) 71 71 ]) 72 72 73 73 lines.extend([ 74 74 '--' + boundary + '--', … … 79 79 class Client: 80 80 """ 81 A class that can act as a client for testing purposes. 82 81 A class that can act as a client for testing purposes. 82 83 83 It allows the user to compose GET and POST requests, and 84 84 obtain the response that the server gave to those requests. … … 89 89 Client objects are stateful - they will retain cookie (and 90 90 thus session) details for the lifetime of the Client instance. 91 91 92 92 This is not intended as a replacement for Twill/Selenium or 93 93 the like - it is here to allow testing against the … … 99 99 self.defaults = defaults 100 100 self.cookie = SimpleCookie() 101 101 102 102 def request(self, **request): 103 103 """ 104 The master request method. Composes the environment dictionary 104 The master request method. Composes the environment dictionary 105 105 and passes to the handler, returning the result of the handler. 106 106 Assumes defaults for the query environment, which can be overridden … … 113 113 'QUERY_STRING': '', 114 114 'REQUEST_METHOD': 'GET', 115 'SCRIPT_NAME': None, 115 'SCRIPT_NAME': None, 116 116 'SERVER_NAME': 'testserver', 117 117 'SERVER_PORT': 80, 118 118 'SERVER_PROTOCOL': 'HTTP/1.1', 119 } 119 } 120 120 environ.update(self.defaults) 121 environ.update(request) 121 environ.update(request) 122 122 123 123 # Curry a data dictionary into an instance of … … 126 126 on_template_render = curry(store_rendered_templates, data) 127 127 dispatcher.connect(on_template_render, signal=signals.template_rendered) 128 128 129 129 response = self.handler(environ) 130 130 131 131 # Add any rendered template detail to the response 132 # If there was only one template rendered (the most likely case), 132 # If there was only one template rendered (the most likely case), 133 133 # flatten the list to a single element 134 134 for detail in ('template', 'context'): … … 140 140 else: 141 141 setattr(response, detail, None) 142 142 143 143 if response.cookies: 144 144 self.cookie.update(response.cookies) 145 145 146 146 return response 147 147 148 148 def get(self, path, data={}, **extra): 149 149 "Request a response from the server using GET." … … 156 156 } 157 157 r.update(extra) 158 158 159 159 return self.request(**r) 160 160 161 161 def post(self, path, data={}, **extra): 162 162 "Request a response from the server using POST." 163 163 164 164 BOUNDARY = 'BoUnDaRyStRiNg' 165 165 … … 174 174 } 175 175 r.update(extra) 176 176 177 177 return self.request(**r) 178 178 … … 181 181 A specialized sequence of GET and POST to log into a view that 182 182 is protected by a @login_required access decorator. 183 183 184 184 path should be the URL of the page that is login protected. 185 186 Returns the response from GETting the requested URL after 185 186 Returns the response from GETting the requested URL after 187 187 login is complete. Returns False if login process failed. 188 188 """ 189 # First, GET the page that is login protected. 189 # First, GET the page that is login protected. 190 190 # This page will redirect to the login page. 191 191 response = self.get(path) 192 192 if response.status_code != 302: 193 193 return False 194 194 195 195 login_path, data = response['Location'].split('?') 196 196 next = data.split('=')[1] … … 200 200 if response.status_code != 200: 201 201 return False 202 202 203 203 # Last, POST the login data. 204 204 form_data = { django/branches/multiple-db-support/docs/faq.txt
r3712 r4151 314 314 .. _`SQLite 3`: http://www.sqlite.org/ 315 315 316 Do I lose anything by using Python 2.3 versus newer Python versions, such as Python 2.5? 317 ---------------------------------------------------------------------------------------- 318 319 No. Django itself is guaranteed to work with any version of Python from 2.3 320 and higher. 321 322 If you use a Python version newer than 2.3, you will, of course, be able to 323 take advantage of newer Python features in your own code, along with the speed 324 improvements and other optimizations that have been made to the Python language 325 itself. But the Django framework itself should work equally well on 2.3 as it 326 does on 2.4 or 2.5. 327 316 328 Do I have to use mod_python? 317 329 ---------------------------- django/branches/multiple-db-support/docs/templates_python.txt
r4139 r4151 367 367 you'll have to activate it. 368 368 369 Writing your own context processors 370 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 371 372 A context processor has a very simple interface: It's just a Python function 373 that takes one argument, an ``HttpRequest`` object, and returns a dictionary 374 that gets added to the template context. Each context processor *must* return 375 a dictionary. 376 377 Custom context processors can live anywhere in your code base. All Django cares 378 about is that your custom context processors are pointed-to by your 379 ``TEMPLATE_CONTEXT_PROCESSORS`` setting. 380 369 381 Loading templates 370 382 ----------------- django/branches/multiple-db-support/tests/regressiontests/dateformat/tests.py
r3712 r4151 22 22 >>> format(my_birthday, 'N') 23 23 'July' 24 >>> format(my_birthday, 'O')25 '+0100' 24 >>> no_tz or format(my_birthday, 'O') == '+0100' 25 True 26 26 >>> format(my_birthday, 'P') 27 27 '10 p.m.' 28 >>> format(my_birthday, 'r')29 'Sun, 8 Jul 1979 22:00:00 +0100' 28 >>> no_tz or format(my_birthday, 'r') == 'Sun, 8 Jul 1979 22:00:00 +0100' 29 True 30 30 >>> format(my_birthday, 's') 31 31 '00' … … 34 34 >>> format(my_birthday, 't') 35 35 '31' 36 >>> format(my_birthday, 'T')37 'CET' 38 >>> format(my_birthday, 'U')39 '300531600' 36 >>> no_tz or format(my_birthday, 'T') == 'CET' 37 True 38 >>> no_tz or format(my_birthday, 'U') == '300531600' 39 True 40 40 >>> format(my_birthday, 'w') 41 41 '0' … … 48 48 >>> format(my_birthday, 'z') 49 49 '189' 50 >>> format(my_birthday, 'Z')51 '3600' 50 >>> no_tz or format(my_birthday, 'Z') == '3600' 51 True 52 52 53 >>> format(summertime, 'I')54 '1' 55 >>> format(summertime, 'O')56 '+0200' 57 >>> format(wintertime, 'I')58 '0' 59 >>> format(wintertime, 'O')60 '+0100' 53 >>> no_tz or format(summertime, 'I') == '1' 54 True 55 >>> no_tz or format(summertime, 'O') == '+0200' 56 True 57 >>> no_tz or format(wintertime, 'I') == '0' 58 True 59 >>> no_tz or format(wintertime, 'O') == '+0100' 60 True 61 61 62 62 >>> format(my_birthday, r'Y z \C\E\T') … … 74 74 translation.activate('en-us') 75 75 76 time.tzset() 76 try: 77 time.tzset() 78 no_tz = False 79 except AttributeError: 80 no_tz = True 77 81 78 82 my_birthday = datetime.datetime(1979, 7, 8, 22, 00) django/branches/multiple-db-support/tests/regressiontests/templates/tests.py
r4139 r4151 170 170 # Escaped backslash using known escape char 171 171 'basic-syntax35': (r'{{ var|default_if_none:"foo\now" }}', {"var": None}, r'foo\now'), 172 173 # Empty strings can be passed as arguments to filters 174 'basic-syntax36': (r'{{ var|join:"" }}', {'var': ['a', 'b', 'c']}, 'abc'), 172 175 173 176 ### COMMENT TAG ###########################################################
