Changeset 5788
- Timestamp:
- 08/02/07 16:51:32 (1 year ago)
- Files:
-
- django/branches/schema-evolution/AUTHORS (modified) (3 diffs)
- django/branches/schema-evolution/django/contrib/auth/models.py (modified) (4 diffs)
- django/branches/schema-evolution/django/contrib/auth/tests.py (copied) (copied from django/trunk/django/contrib/auth/tests.py)
- django/branches/schema-evolution/django/contrib/databrowse/plugins/fieldchoices.py (modified) (1 diff)
- django/branches/schema-evolution/django/contrib/databrowse/templates/databrowse/calendar_day.html (modified) (1 diff)
- django/branches/schema-evolution/django/contrib/databrowse/templates/databrowse/calendar_month.html (modified) (1 diff)
- django/branches/schema-evolution/django/contrib/databrowse/templates/databrowse/choice_detail.html (modified) (1 diff)
- django/branches/schema-evolution/django/contrib/databrowse/templates/databrowse/choice_list.html (modified) (1 diff)
- django/branches/schema-evolution/django/contrib/databrowse/templates/databrowse/homepage.html (modified) (1 diff)
- django/branches/schema-evolution/django/contrib/databrowse/templates/databrowse/model_detail.html (modified) (1 diff)
- django/branches/schema-evolution/django/contrib/databrowse/templates/databrowse/object_detail.html (modified) (3 diffs)
- django/branches/schema-evolution/django/core/management.py (modified) (4 diffs)
- django/branches/schema-evolution/django/db/models/fields/__init__.py (modified) (1 diff)
- django/branches/schema-evolution/django/db/models/manager.py (modified) (1 diff)
- django/branches/schema-evolution/django/db/models/query.py (modified) (2 diffs)
- django/branches/schema-evolution/django/newforms/forms.py (modified) (2 diffs)
- django/branches/schema-evolution/django/newforms/widgets.py (modified) (3 diffs)
- django/branches/schema-evolution/django/shortcuts/__init__.py (modified) (1 diff)
- django/branches/schema-evolution/django/template/loaders/app_directories.py (modified) (2 diffs)
- django/branches/schema-evolution/django/template/loaders/filesystem.py (modified) (2 diffs)
- django/branches/schema-evolution/django/test/client.py (modified) (1 diff)
- django/branches/schema-evolution/django/test/simple.py (modified) (6 diffs)
- django/branches/schema-evolution/django/test/testcases.py (modified) (1 diff)
- django/branches/schema-evolution/django/test/utils.py (modified) (1 diff)
- django/branches/schema-evolution/django/utils/http.py (modified) (1 diff)
- django/branches/schema-evolution/django/utils/_os.py (copied) (copied from django/trunk/django/utils/_os.py)
- django/branches/schema-evolution/docs/authentication.txt (modified) (4 diffs)
- django/branches/schema-evolution/docs/contributing.txt (modified) (1 diff)
- django/branches/schema-evolution/docs/db-api.txt (modified) (4 diffs)
- django/branches/schema-evolution/docs/model-api.txt (modified) (1 diff)
- django/branches/schema-evolution/docs/testing.txt (modified) (4 diffs)
- django/branches/schema-evolution/tests/modeltests/get_object_or_404/models.py (modified) (3 diffs)
- django/branches/schema-evolution/tests/modeltests/lookup/models.py (modified) (2 diffs)
- django/branches/schema-evolution/tests/modeltests/test_client/models.py (modified) (1 diff)
- django/branches/schema-evolution/tests/modeltests/test_client/views.py (modified) (2 diffs)
- django/branches/schema-evolution/tests/regressiontests/forms/tests.py (modified) (3 diffs)
- django/branches/schema-evolution/tests/regressiontests/model_fields (copied) (copied from django/trunk/tests/regressiontests/model_fields)
- django/branches/schema-evolution/tests/regressiontests/model_fields/__init__.py (copied) (copied from django/trunk/tests/regressiontests/model_fields/__init__.py)
- django/branches/schema-evolution/tests/regressiontests/model_fields/models.py (copied) (copied from django/trunk/tests/regressiontests/model_fields/models.py)
- django/branches/schema-evolution/tests/regressiontests/model_fields/tests.py (copied) (copied from django/trunk/tests/regressiontests/model_fields/tests.py)
- django/branches/schema-evolution/tests/regressiontests/templates/tests.py (modified) (2 diffs)
- django/branches/schema-evolution/tests/regressiontests/test_client_regress/models.py (modified) (1 diff)
- django/branches/schema-evolution/tests/runtests.py (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/schema-evolution/AUTHORS
r5734 r5788 118 118 martin.glueck@gmail.com 119 119 GomoX <gomo@datafull.com> 120 Mario Gonzalez <gonzalemario @tgmail.com>120 Mario Gonzalez <gonzalemario@gmail.com> 121 121 Simon Greenhill <dev@simon.net.nz> 122 122 Owen Griffiths … … 215 215 Daniel Poelzleithner <http://poelzi.org/> 216 216 polpak@yahoo.com 217 Johann Queuniet <johann.queuniet@adh.naellia.eu> 217 218 J. Rademaker 218 219 Michael Radziej <mir@noris.de> … … 243 244 nowell strite 244 245 Sundance 246 SuperJared 245 247 Radek Švarz <http://www.svarz.cz/translate/> 246 248 Swaroop C H <http://www.swaroopch.info> django/branches/schema-evolution/django/contrib/auth/models.py
r5734 r5788 7 7 import datetime 8 8 import urllib 9 10 UNUSABLE_PASSWORD = '!' # This will never be a valid hash 9 11 10 12 try: … … 84 86 85 87 class UserManager(models.Manager): 86 def create_user(self, username, email, password ):88 def create_user(self, username, email, password=None): 87 89 "Creates and saves a User with the given username, e-mail and password." 88 90 now = datetime.datetime.now() 89 91 user = self.model(None, username, '', '', email.strip().lower(), 'placeholder', False, True, False, now, now) 90 user.set_password(password) 92 if password: 93 user.set_password(password) 94 else: 95 user.set_unusable_password() 91 96 user.save() 92 97 return user … … 179 184 return is_correct 180 185 return check_password(raw_password, self.password) 186 187 def set_unusable_password(self): 188 # Sets a value that will never be a valid hash 189 self.password = UNUSABLE_PASSWORD 190 191 def has_usable_password(self): 192 return self.password != UNUSABLE_PASSWORD 181 193 182 194 def get_group_permissions(self): … … 269 281 270 282 class Message(models.Model): 271 """The message system is a lightweight way to queue messages for given users. A message is associated with a User instance (so it is only applicable for registered users). There's no concept of expiration or timestamps. Messages are created by the Django admin after successful actions. For example, "The poll Foo was created successfully." is a message. 283 """ 284 The message system is a lightweight way to queue messages for given users. A message is associated with a User instance (so it is only applicable for registered users). There's no concept of expiration or timestamps. Messages are created by the Django admin after successful actions. For example, "The poll Foo was created successfully." is a message. 272 285 """ 273 286 user = models.ForeignKey(User) django/branches/schema-evolution/django/contrib/databrowse/plugins/fieldchoices.py
r5734 r5788 38 38 def urls(self, plugin_name, easy_instance_field): 39 39 if easy_instance_field.field in self.field_dict(easy_instance_field.model.model).values(): 40 field_value = smart_str(easy_instance_field.raw_value) 40 41 return [u'%s%s/%s/%s/' % (easy_instance_field.model.url(), 41 42 plugin_name, easy_instance_field.field.name, 42 urllib.quote( smart_str(easy_instance_field.raw_value)))]43 urllib.quote(field_value, safe=''))] 43 44 44 45 def model_view(self, request, model_databrowse, url): django/branches/schema-evolution/django/contrib/databrowse/templates/databrowse/calendar_day.html
r5734 r5788 11 11 <ul class="objectlist"> 12 12 {% for object in object_list %} 13 <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object }}</a></li>13 <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 14 14 {% endfor %} 15 15 </ul> django/branches/schema-evolution/django/contrib/databrowse/templates/databrowse/calendar_month.html
r5734 r5788 11 11 <ul class="objectlist"> 12 12 {% for object in object_list %} 13 <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object }}</a></li>13 <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 14 14 {% endfor %} 15 15 </ul> django/branches/schema-evolution/django/contrib/databrowse/templates/databrowse/choice_detail.html
r5734 r5788 11 11 <ul class="objectlist"> 12 12 {% for object in object_list %} 13 <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object }}</a></li>13 <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 14 14 {% endfor %} 15 15 </ul> django/branches/schema-evolution/django/contrib/databrowse/templates/databrowse/choice_list.html
r5734 r5788 11 11 <ul class="objectlist"> 12 12 {% for choice in field.choices %} 13 <li class="{% cycle odd,even %}"><a href="{{ choice.url }}">{{ choice.label }}</a></li>13 <li class="{% cycle odd,even %}"><a href="{{ choice.url }}">{{ choice.label|escape }}</a></li> 14 14 {% endfor %} 15 15 </ul> django/branches/schema-evolution/django/contrib/databrowse/templates/databrowse/homepage.html
r5734 r5788 12 12 <p> 13 13 {% for object in model.sample_objects %} 14 <a href="{{ object.url }}">{{ object }}</a>,14 <a href="{{ object.url }}">{{ object|escape }}</a>, 15 15 {% endfor %} 16 16 <a class="more" href="{{ model.url }}">More →</a> django/branches/schema-evolution/django/contrib/databrowse/templates/databrowse/model_detail.html
r5734 r5788 13 13 <ul class="objectlist"> 14 14 {% for object in model.objects %} 15 <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object }}</a></li>15 <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 16 16 {% endfor %} 17 17 </ul> django/branches/schema-evolution/django/contrib/databrowse/templates/databrowse/object_detail.html
r5734 r5788 5 5 {% block content %} 6 6 7 <div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ object.model.url }}">{{ object.model.verbose_name_plural|capfirst }}</a> / {{ object }}</div>7 <div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ object.model.url }}">{{ object.model.verbose_name_plural|capfirst }}</a> / {{ object|escape }}</div> 8 8 9 <h1>{{ object.model.verbose_name|capfirst }}: {{ object }}</h1>9 <h1>{{ object.model.verbose_name|capfirst }}: {{ object|escape }}</h1> 10 10 11 11 <table class="objectinfo"> … … 15 15 <td> 16 16 {% if field.urls %} 17 {% for urlvaluein field.urls %}18 {% if url value.1 %}<a href="{{ urlvalue.1 }}">{% endif %}{{ urlvalue.0 }}{% if urlvalue.1%}</a>{% endif %}{% if not forloop.last %}, {% endif %}17 {% for value, url in field.urls %} 18 {% if url %}<a href="{{ url }}">{% endif %}{{ value|escape }}{% if url %}</a>{% endif %}{% if not forloop.last %}, {% endif %} 19 19 {% endfor %} 20 20 {% else %}None{% endif %} … … 30 30 <ul class="objectlist"> 31 31 {% for object in related_object.object_list %} 32 <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object }}</a></li>32 <li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li> 33 33 {% endfor %} 34 34 </ul> django/branches/schema-evolution/django/core/management.py
r5787 r5788 1455 1455 error_text = str(e) 1456 1456 sys.stderr.write(style.ERROR("Error: %s" % error_text) + '\n') 1457 sys.exit(1) 1457 # Need to use an OS exit because sys.exit doesn't work in a thread 1458 os._exit(1) 1458 1459 except KeyboardInterrupt: 1459 1460 sys.exit(0) … … 1549 1550 runfcgi.args = '[various KEY=val options, use `runfcgi help` for help]' 1550 1551 1551 def test( app_labels, verbosity=1):1552 def test(test_labels, verbosity=1, interactive=True): 1552 1553 "Runs the test suite for the specified applications" 1553 1554 from django.conf import settings 1554 1555 from django.db.models import get_app, get_apps 1555 1556 if len(app_labels) == 0: 1557 app_list = get_apps() 1558 else: 1559 app_list = [get_app(app_label) for app_label in app_labels] 1560 1556 1561 1557 test_path = settings.TEST_RUNNER.split('.') 1562 1558 # Allow for Python 2.5 relative paths … … 1568 1564 test_runner = getattr(test_module, test_path[-1]) 1569 1565 1570 failures = test_runner( app_list, verbosity)1566 failures = test_runner(test_labels, verbosity=verbosity, interactive=interactive) 1571 1567 if failures: 1572 1568 sys.exit(failures) 1573 1569 1574 1570 test.help_doc = 'Runs the test suite for the specified applications, or the entire site if no apps are specified' 1575 test.args = '[--verbosity] ' + APP_ARGS1571 test.args = '[--verbosity] [--noinput]' + APP_ARGS 1576 1572 1577 1573 def load_data(fixture_labels, verbosity=1): … … 1850 1846 except IndexError: 1851 1847 parser.print_usage_and_exit() 1852 elif action in ('test', 'loaddata'): 1848 elif action == 'test': 1849 try: 1850 action_mapping[action](args[1:], int(options.verbosity), options.interactive) 1851 except IndexError: 1852 parser.print_usage_and_exit() 1853 elif action == 'loaddata': 1853 1854 try: 1854 1855 action_mapping[action](args[1:], int(options.verbosity)) django/branches/schema-evolution/django/db/models/fields/__init__.py
r5735 r5788 622 622 return decimal.Decimal(value) 623 623 except decimal.InvalidOperation: 624 raise validators.ValidationError, ugettext("This value must be a decimal number.") 624 raise validators.ValidationError( 625 _("This value must be a decimal number.")) 625 626 626 627 def _format(self, value): django/branches/schema-evolution/django/db/models/manager.py
r5734 r5788 3 3 from django.db.models import signals 4 4 from django.db.models.fields import FieldDoesNotExist 5 6 # Size of each "chunk" for get_iterator calls.7 # Larger values are slightly faster at the expense of more storage space.8 GET_ITERATOR_CHUNK_SIZE = 1009 5 10 6 def ensure_default_manager(sender): django/branches/schema-evolution/django/db/models/query.py
r5734 r5788 580 580 raise StopIteration 581 581 582 # self._fields is a list of field names to fetch. 582 # self._select is a dictionary, and dictionaries' key order is 583 # undefined, so we convert it to a list of tuples. 584 extra_select = self._select.items() 585 586 # Construct two objects -- fields and field_names. 587 # fields is a list of Field objects to fetch. 588 # field_names is a list of field names, which will be the keys in the 589 # resulting dictionaries. 583 590 if self._fields: 584 if not self._select:591 if not extra_select: 585 592 fields = [self.model._meta.get_field(f, many_to_many=False) for f in self._fields] 593 field_names = self._fields 586 594 else: 587 595 fields = [] 596 field_names = [] 588 597 for f in self._fields: 589 598 if f in [field.name for field in self.model._meta.fields]: 590 599 fields.append(self.model._meta.get_field(f, many_to_many=False)) 591 elif not self._select.has_key( f ): 592 raise FieldDoesNotExist, '%s has no field named %r' % ( self.model._meta.object_name, f ) 593 594 field_names = self._fields 600 field_names.append(f) 601 elif not self._select.has_key(f): 602 raise FieldDoesNotExist('%s has no field named %r' % (self.model._meta.object_name, f)) 595 603 else: # Default to all fields. 596 604 fields = self.model._meta.fields … … 599 607 columns = [f.column for f in fields] 600 608 select = ['%s.%s' % (backend.quote_name(self.model._meta.db_table), backend.quote_name(c)) for c in columns] 601 # Add any additional SELECTs.602 if self._select:603 select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), backend.quote_name(s[0])) for s in self._select.items()])609 if extra_select: 610 select.extend(['(%s) AS %s' % (quote_only_if_word(s[1]), backend.quote_name(s[0])) for s in extra_select]) 611 field_names.extend([f[0] for f in extra_select]) 604 612 605 613 cursor = connection.cursor() django/branches/schema-evolution/django/newforms/forms.py
r5734 r5788 233 233 234 234 def __unicode__(self): 235 "Renders this field as an HTML widget." 236 # Use the 'widget' attribute on the field to determine which type 237 # of HTML widget to use. 238 value = self.as_widget(self.field.widget) 239 if not isinstance(value, basestring): 240 # Some Widget render() methods -- notably RadioSelect -- return a 241 # "special" object rather than a string. Call __unicode__() on that 242 # object to get its rendered value. 243 value = unicode(value) 244 return value 235 """Renders this field as an HTML widget.""" 236 return self.as_widget() 245 237 246 238 def _errors(self): … … 252 244 errors = property(_errors) 253 245 254 def as_widget(self, widget, attrs=None): 246 def as_widget(self, widget=None, attrs=None): 247 """ 248 Renders the field by rendering the passed widget, adding any HTML 249 attributes passed as attrs. If no widget is specified, then the 250 field's default widget will be used. 251 """ 252 if not widget: 253 widget = self.field.widget 255 254 attrs = attrs or {} 256 255 auto_id = self.auto_id django/branches/schema-evolution/django/newforms/widgets.py
r5734 r5788 217 217 218 218 class RadioInput(StrAndUnicode): 219 "An object used by RadioFieldRenderer that represents a single <input type='radio'>." 219 """ 220 An object used by RadioFieldRenderer that represents a single 221 <input type='radio'>. 222 """ 223 220 224 def __init__(self, name, value, attrs, choice, index): 221 225 self.name, self.value = name, value … … 240 244 241 245 class RadioFieldRenderer(StrAndUnicode): 242 "An object used by RadioSelect to enable customization of radio widgets." 246 """ 247 An object used by RadioSelect to enable customization of radio widgets. 248 """ 249 243 250 def __init__(self, name, value, attrs, choices): 244 251 self.name, self.value, self.attrs = name, value, attrs … … 254 261 255 262 def __unicode__(self): 256 "Outputs a <ul> for this set of radio fields." 263 return self.render() 264 265 def render(self): 266 """Outputs a <ul> for this set of radio fields.""" 257 267 return u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>' % force_unicode(w) for w in self]) 258 268 259 269 class RadioSelect(Select): 260 def render(self, name, value, attrs=None, choices=()): 261 "Returns a RadioFieldRenderer instance rather than a Unicode string." 270 271 def __init__(self, *args, **kwargs): 272 self.renderer = kwargs.pop('renderer', None) 273 if not self.renderer: 274 self.renderer = RadioFieldRenderer 275 super(RadioSelect, self).__init__(*args, **kwargs) 276 277 def get_renderer(self, name, value, attrs=None, choices=()): 278 """Returns an instance of the renderer.""" 262 279 if value is None: value = '' 263 280 str_value = force_unicode(value) # Normalize to string. 264 281 final_attrs = self.build_attrs(attrs) 265 return RadioFieldRenderer(name, str_value, final_attrs, list(chain(self.choices, choices))) 282 choices = list(chain(self.choices, choices)) 283 return self.renderer(name, str_value, final_attrs, choices) 284 285 def render(self, name, value, attrs=None, choices=()): 286 return self.get_renderer(name, value, attrs, choices).render() 266 287 267 288 def id_for_label(self, id_): django/branches/schema-evolution/django/shortcuts/__init__.py
r5734 r5788 1 # This module collects helper functions and classes that "span" multiple levels 2 # of MVC. In other words, these functions/classes introduce controlled coupling 3 # for convenience's sake. 1 """ 2 This module collects helper functions and classes that "span" multiple levels 3 of MVC. In other words, these functions/classes introduce controlled coupling 4 for convenience's sake. 5 """ 4 6 5 7 from django.template import loader 6 8 from django.http import HttpResponse, Http404 7 9 from django.db.models.manager import Manager 10 from django.db.models.query import QuerySet 8 11 9 12 def render_to_response(*args, **kwargs): 13 """ 14 Returns a HttpResponse whose content is filled with the result of calling 15 django.template.loader.render_to_string() with the passed arguments. 16 """ 10 17 return HttpResponse(loader.render_to_string(*args, **kwargs)) 11 18 load_and_render = render_to_response # For backwards compatibility. 12 19 13 def get_object_or_404(klass, *args, **kwargs): 14 if isinstance(klass, Manager): 15 manager = klass 16 klass = manager.model 17 else: 18 manager = klass._default_manager 19 try: 20 return manager.get(*args, **kwargs) 21 except klass.DoesNotExist: 22 raise Http404('No %s matches the given query.' % klass._meta.object_name) 23 24 def get_list_or_404(klass, *args, **kwargs): 25 if isinstance(klass, Manager): 20 def _get_queryset(klass): 21 """ 22 Returns a QuerySet from a Model, Manager, or QuerySet. Created to make 23 get_object_or_404 and get_list_or_404 more DRY. 24 """ 25 if isinstance(klass, QuerySet): 26 return klass 27 elif isinstance(klass, Manager): 26 28 manager = klass 27 29 else: 28 30 manager = klass._default_manager 29 obj_list = list(manager.filter(*args, **kwargs)) 31 return manager.all() 32 33 def get_object_or_404(klass, *args, **kwargs): 34 """ 35 Uses get() to return an object, or raises a Http404 exception if the object 36 does not exist. 37 38 klass may be a Model, Manager, or QuerySet object. All other passed 39 arguments and keyword arguments are used in the get() query. 40 41 Note: Like with get(), an AssertionError will be raised if more than one 42 object is found. 43 """ 44 queryset = _get_queryset(klass) 45 try: 46 return queryset.get(*args, **kwargs) 47 except queryset.model.DoesNotExist: 48 raise Http404('No %s matches the given query.' % queryset.model._meta.object_name) 49 50 def get_list_or_404(klass, *args, **kwargs): 51 """ 52 Uses filter() to return a list of objects, or raise a Http404 exception if 53 the list is empty. 54 55 klass may be a Model, Manager, or QuerySet object. All other passed 56 arguments and keyword arguments are used in the filter() query. 57 """ 58 queryset = _get_queryset(klass) 59 obj_list = list(queryset.filter(*args, **kwargs)) 30 60 if not obj_list: 31 raise Http404('No %s matches the given query.' % manager.model._meta.object_name)61 raise Http404('No %s matches the given query.' % queryset.model._meta.object_name) 32 62 return obj_list django/branches/schema-evolution/django/template/loaders/app_directories.py
r5734 r5788 1 # Wrapper for loading templates from "template" directories in installed app packages. 1 """ 2 Wrapper for loading templates from "template" directories in INSTALLED_APPS 3 packages. 4 """ 5 6 import os 2 7 3 8 from django.conf import settings 4 9 from django.core.exceptions import ImproperlyConfigured 5 10 from django.template import TemplateDoesNotExist 6 import os 11 from django.utils._os import safe_join 7 12 8 13 # At compile time, cache the directories to search. … … 29 34 30 35 def get_template_sources(template_name, template_dirs=None): 31 for template_dir in app_template_dirs: 32 yield os.path.join(template_dir, template_name) 36 if not template_dirs: 37 template_dirs = app_template_dirs 38 for template_dir in template_dirs: 39 try: 40 yield safe_join(template_dir, template_name) 41 except ValueError: 42 # The joined path was located outside of template_dir. 43 pass 33 44 34 45 def load_template_source(template_name, template_dirs=None): django/branches/schema-evolution/django/template/loaders/filesystem.py
r5734 r5788 1 # Wrapper for loading templates from the filesystem. 1 """ 2 Wrapper for loading templates from the filesystem. 3 """ 2 4 3 5 from django.conf import settings 4 6 from django.template import TemplateDoesNotExist 5 import os 7 from django.utils._os import safe_join 6 8 7 9 def get_template_sources(template_name, template_dirs=None): … … 9 11 template_dirs = settings.TEMPLATE_DIRS 10 12 for template_dir in template_dirs: 11 yield os.path.join(template_dir, template_name) 13 try: 14 yield safe_join(template_dir, template_name) 15 except ValueError: 16 # The joined path was located outside of template_dir. 17 pass 12 18 13 19 def load_template_source(template_name, template_dirs=None): django/branches/schema-evolution/django/test/client.py
r5734 r5788 196 196 'CONTENT_TYPE': 'text/html; charset=utf-8', 197 197 'PATH_INFO': path, 198 'QUERY_STRING': urlencode(data ),198 'QUERY_STRING': urlencode(data, doseq=True), 199 199 'REQUEST_METHOD': 'GET', 200 200 } django/branches/schema-evolution/django/test/simple.py
r5785 r5788 1 1 import unittest 2 2 from django.conf import settings 3 from django.db.models import get_app, get_apps 3 4 from django.test import _doctest as doctest 4 5 from django.test.utils import setup_test_environment, teardown_test_environment … … 11 12 doctestOutputChecker = OutputChecker() 12 13 14 def get_tests(app_module): 15 try: 16 app_path = app_module.__name__.split('.')[:-1] 17 test_module = __import__('.'.join(app_path + [TEST_MODULE]), {}, {}, TEST_MODULE) 18 except ImportError, e: 19 # Couldn't import tests.py. Was it due to a missing file, or 20 # due to an import error in a tests.py that actually exists? 21 import os.path 22 from imp import find_module 23 try: 24 mod = find_module(TEST_MODULE, [os.path.dirname(app_module.__file__)]) 25 except ImportError: 26 # 'tests' module doesn't exist. Move on. 27 test_module = None 28 else: 29 # The module exists, so there must be an import error in the 30 # test module itself. We don't need the module; so if the 31 # module was a single file module (i.e., tests.py), close the file 32 # handle returned by find_module. Otherwise, the test module 33 # is a directory, and there is nothing to close. 34 if mod[0]: 35 mod[0].close() 36 raise 37 return test_module 38 13 39 def build_suite(app_module): 14 40 "Create a complete Django test suite for the provided application module" … … 31 57 # Check to see if a separate 'tests' module exists parallel to the 32 58 # models module 33 try: 34 app_path = app_module.__name__.split('.')[:-1] 35 test_module = __import__('.'.join(app_path + [TEST_MODULE]), {}, {}, TEST_MODULE) 36 59 test_module = get_tests(app_module) 60 if test_module: 37 61 # Load unit and doctests in the tests.py module. If module has 38 62 # a suite() method, use it. Otherwise build the test suite ourselves. … … 48 72 # No doc tests in tests.py 49 73 pass 50 except ImportError, e:51 # Couldn't import tests.py. Was it due to a missing file, or52 # due to an import error in a tests.py that actually exists?53 import os.path54 from imp import find_module55 try:56 mod = find_module(TEST_MODULE, [os.path.dirname(app_module.__file__)])57 except ImportError:58 # 'tests' module doesn't exist. Move on.59 pass60 else:61 # The module exists, so there must be an import error in the62 # test module itself. We don't need the module; so if the63 # module was a single file module (i.e., tests.py), close the file64 # handle returned by find_module. Otherwise, the test module65 # is a directory, and there is nothing to close.66 if mod[0]:67 mod[0].close()68 raise69 70 74 return suite 71 75 72 def run_tests(module_list, verbosity=1, extra_tests=[]): 76 def build_test(label): 77 """Construct a test case a test with the specified label. Label should 78 be of the form model.TestClass or model.TestClass.test_method. Returns 79 an instantiated test or test suite corresponding to the label provided. 80 73 81 """ 74 Run the unit tests for all the modules in the provided list. 75 This testrunner will search each of the modules in the provided list, 76 looking for doctests and unittests in models.py or tests.py within 77 the module. A list of 'extra' tests may also be provided; these tests 82 parts = label.split('.') 83 if len(parts) < 2 or len(parts) > 3: 84 raise ValueError("Test label '%s' should be of the form app.TestCase or app.TestCase.test_method" % label) 85 86 app_module = get_app(parts[0]) 87 TestClass = getattr(app_module, parts[1], None) 88 89 # Couldn't find the test class in models.py; look in tests.py 90 if TestClass is None: 91 test_module = get_tests(app_module) 92 if test_module: 93 TestClass = getattr(test_module, parts[1], None) 94 95 if len(parts) == 2: # label is app.TestClass 96 try: 97 return unittest.TestLoader().loadTestsFromTestCase(TestClass) 98 except TypeError: 99 raise ValueError("Test label '%s' does not refer to a test class" % label) 100 else: # label is app.TestClass.test_method 101 return TestClass(parts[2]) 102 103 def run_tests(test_labels, verbosity=1, interactive=True, extra_tests=[]): 104 """ 105 Run the unit tests for all the test labels in the provided list. 106 Labels must be of the form: 107 - app.TestClass.test_method 108 Run a single specific test method 109 - app.TestClass 110 Run all the test methods in a given class 111 - app 112 Search for doctests and unittests in the named application. 113 114 When looking for tests, the test runner will look in the models and 115 tests modules for the application. 116 117 A list of 'extra' tests may also be provided; these tests 78 118 will be added to the test suite. 79 119 … … 84 124 settings.DEBUG = False 85 125 suite = unittest.TestSuite() 86 87 for module in module_list: 88 suite.addTest(build_suite(module)) 126 127 if test_labels: 128 for label in test_labels: 129 if '.' in label: 130 suite.addTest(build_test(label)) 131 else: 132 app = get_app(label) 133 suite.addTest(build_suite(app)) 134 else: 135 for app in get_apps(): 136 suite.addTest(build_suite(app)) 89 137 90 138 for test in extra_tests: … … 92 140 93 141 old_name = settings.DATABASE_NAME 94 create_test_db(verbosity )142 create_test_db(verbosity, autoclobber=not interactive) 95 143 result = unittest.TextTestRunner(verbosity=verbosity).run(suite) 96 144 destroy_test_db(old_name, verbosity) django/branches/schema-evolution/django/test/testcases.py
r5734 r5788 85 85 (response.status_code, status_code)) 86 86 real_count = response.content.count(text) 87 if count :87 if count is not None: 88 88 self.assertEqual(real_count, count, 89 89 "Found %d instances of '%s' in response (expected %d)" % (real_count, text, count)) django/branches/schema-evolution/django/test/utils.py
r5734 r5788 145 145 management.syncdb(verbosity, interactive=False) 146 146 147 if settings.CACHE_BACKEND.startswith('db://'): 148 cache_name = settings.CACHE_BACKEND[len('db://'):] 149 management.createcachetable(cache_name) 150 147 151 # Get a cursor (even though we don't need one yet). This has 148 152 # the side effect of initializing the test database. django/branches/schema-evolution/django/utils/http.py
r5734 r5788 31 31 if hasattr(query, 'items'): 32 32 query = query.items() 33 return urllib.urlencode([(smart_str(k), smart_str(v)) for k, 34 v in query], doseq) 33 return urllib.urlencode( 34 [(smart_str(k), 35 isinstance(v, (list,tuple)) and [smart_str(i) for i in v] or smart_str(v)) 36 for k, v in query],
