Changeset 3732
- Timestamp:
- 09/06/06 20:36:27 (2 years ago)
- Files:
-
- django/branches/per-object-permissions/AUTHORS (modified) (4 diffs)
- django/branches/per-object-permissions/django/bin/compile-messages.py (modified) (1 diff)
- django/branches/per-object-permissions/django/conf/global_settings.py (modified) (1 diff)
- django/branches/per-object-permissions/django/contrib/admin/templates/admin/change_form.html (modified) (1 diff)
- django/branches/per-object-permissions/django/contrib/admin/templatetags/admin_modify.py (modified) (1 diff)
- django/branches/per-object-permissions/django/contrib/admin/views/doc.py (modified) (1 diff)
- django/branches/per-object-permissions/django/contrib/auth/models.py (modified) (1 diff)
- django/branches/per-object-permissions/django/contrib/sitemaps (copied) (copied from django/trunk/django/contrib/sitemaps)
- django/branches/per-object-permissions/django/contrib/sitemaps/__init__.py (copied) (copied from django/trunk/django/contrib/sitemaps/__init__.py)
- django/branches/per-object-permissions/django/contrib/sitemaps/templates (copied) (copied from django/trunk/django/contrib/sitemaps/templates)
- django/branches/per-object-permissions/django/contrib/sitemaps/templates/sitemap_index.xml (copied) (copied from django/trunk/django/contrib/sitemaps/templates/sitemap_index.xml)
- django/branches/per-object-permissions/django/contrib/sitemaps/templates/sitemap.xml (copied) (copied from django/trunk/django/contrib/sitemaps/templates/sitemap.xml)
- django/branches/per-object-permissions/django/contrib/sitemaps/views.py (copied) (copied from django/trunk/django/contrib/sitemaps/views.py)
- django/branches/per-object-permissions/django/core/management.py (modified) (1 diff)
- django/branches/per-object-permissions/django/core/serializers/base.py (modified) (16 diffs)
- django/branches/per-object-permissions/django/core/serializers/json.py (modified) (1 diff)
- django/branches/per-object-permissions/django/db/backends/postgresql_psycopg2/base.py (modified) (3 diffs)
- django/branches/per-object-permissions/django/db/backends/sqlite3/base.py (modified) (1 diff)
- django/branches/per-object-permissions/django/db/backends/util.py (modified) (1 diff)
- django/branches/per-object-permissions/django/template/defaulttags.py (modified) (3 diffs)
- django/branches/per-object-permissions/django/template/__init__.py (modified) (5 diffs)
- django/branches/per-object-permissions/django/template/loader.py (modified) (1 diff)
- django/branches/per-object-permissions/django/template/loader_tags.py (modified) (2 diffs)
- django/branches/per-object-permissions/django/test/client.py (modified) (4 diffs)
- django/branches/per-object-permissions/django/test/signals.py (copied) (copied from django/trunk/django/test/signals.py)
- django/branches/per-object-permissions/django/test/simple.py (modified) (3 diffs)
- django/branches/per-object-permissions/django/test/utils.py (modified) (8 diffs)
- django/branches/per-object-permissions/django/utils/datastructures.py (modified) (1 diff)
- django/branches/per-object-permissions/django/views/debug.py (modified) (11 diffs)
- django/branches/per-object-permissions/django/views/static.py (modified) (1 diff)
- django/branches/per-object-permissions/docs/add_ons.txt (modified) (1 diff)
- django/branches/per-object-permissions/docs/contributing.txt (modified) (1 diff)
- django/branches/per-object-permissions/docs/django-admin.txt (modified) (3 diffs)
- django/branches/per-object-permissions/docs/faq.txt (modified) (2 diffs)
- django/branches/per-object-permissions/docs/settings.txt (modified) (1 diff)
- django/branches/per-object-permissions/docs/sitemaps.txt (copied) (copied from django/trunk/docs/sitemaps.txt)
- django/branches/per-object-permissions/docs/sites.txt (modified) (1 diff)
- django/branches/per-object-permissions/docs/syndication_feeds.txt (modified) (1 diff)
- django/branches/per-object-permissions/docs/templates_python.txt (modified) (2 diffs)
- django/branches/per-object-permissions/docs/testing.txt (copied) (copied from django/trunk/docs/testing.txt)
- django/branches/per-object-permissions/setup.cfg (copied) (copied from django/trunk/setup.cfg)
- django/branches/per-object-permissions/tests/modeltests/get_latest/models.py (modified) (2 diffs)
- django/branches/per-object-permissions/tests/modeltests/test_client (copied) (copied from django/trunk/tests/modeltests/test_client)
- django/branches/per-object-permissions/tests/modeltests/test_client/__init__.py (copied) (copied from django/trunk/tests/modeltests/test_client/__init__.py)
- django/branches/per-object-permissions/tests/modeltests/test_client/management.py (copied) (copied from django/trunk/tests/modeltests/test_client/management.py)
- django/branches/per-object-permissions/tests/modeltests/test_client/models.py (copied) (copied from django/trunk/tests/modeltests/test_client/models.py)
- django/branches/per-object-permissions/tests/modeltests/test_client/urls.py (copied) (copied from django/trunk/tests/modeltests/test_client/urls.py)
- django/branches/per-object-permissions/tests/modeltests/test_client/views.py (copied) (copied from django/trunk/tests/modeltests/test_client/views.py)
- django/branches/per-object-permissions/tests/regressiontests/templates/tests.py (modified) (8 diffs)
- django/branches/per-object-permissions/tests/runtests.py (modified) (3 diffs)
- django/branches/per-object-permissions/tests/templates (copied) (copied from django/trunk/tests/templates)
- django/branches/per-object-permissions/tests/templates/404.html (copied) (copied from django/trunk/tests/templates/404.html)
- django/branches/per-object-permissions/tests/templates/500.html (copied) (copied from django/trunk/tests/templates/500.html)
- django/branches/per-object-permissions/tests/templates/login.html (copied) (copied from django/trunk/tests/templates/login.html)
- django/branches/per-object-permissions/tests/urls.py (copied) (copied from django/trunk/tests/urls.py)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/per-object-permissions/AUTHORS
r3630 r3732 105 105 Jason McBrayer <http://www.carcosa.net/jason/> 106 106 michael.mcewan@gmail.com 107 mir@noris.de108 107 mmarshall 109 108 Eric Moritz <http://eric.themoritzfamily.com/> … … 122 121 Daniel Poelzleithner <http://poelzi.org/> 123 122 J. Rademaker 123 Michael Radziej <mir@noris.de> 124 124 Brian Ray <http://brianray.chipy.org/> 125 125 rhettg@gmail.com … … 127 127 Ivan Sagalaev (Maniac) <http://www.softwaremaniacs.org/> 128 128 David Schein 129 Pete Shinners <pete@shinners.org> 130 SmileyChris <smileychris@gmail.com> 129 131 sopel 130 132 Thomas Steinacher <tom@eggdrop.ch> … … 139 141 Geert Vanderkelen 140 142 Milton Waddams 143 Dan Watson <http://theidioteque.net/> 141 144 Rachel Willmer <http://www.willmer.com/kb/> 142 145 wojtek django/branches/per-object-permissions/django/bin/compile-messages.py
r3630 r3732 27 27 os.environ['djangocompilemo'] = pf + '.mo' 28 28 os.environ['djangocompilepo'] = pf + '.po' 29 cmd = 'msgfmt -o "$djangocompilemo" "$djangocompilepo"' 29 if sys.platform == 'win32': # Different shell-variable syntax 30 cmd = 'msgfmt -o "%djangocompilemo%" "%djangocompilepo%"' 31 else: 32 cmd = 'msgfmt -o "$djangocompilemo" "$djangocompilepo"' 30 33 os.system(cmd) 31 34 django/branches/per-object-permissions/django/conf/global_settings.py
r3669 r3732 302 302 ########### 303 303 304 TEST_RUNNER='django.test.simple.run_tests' 304 # The name of the method to use to invoke the test suite 305 TEST_RUNNER = 'django.test.simple.run_tests' 306 307 # The name of the database to use for testing purposes. 308 # If None, a name of 'test_' + DATABASE_NAME will be assumed 309 TEST_DATABASE_NAME = None django/branches/per-object-permissions/django/contrib/admin/templates/admin/change_form.html
r3629 r3732 70 70 71 71 </div> 72 73 72 74 {% endblock %} django/branches/per-object-permissions/django/contrib/admin/templatetags/admin_modify.py
r3669 r3732 145 145 fields = self.relation.editable_fields() 146 146 self.field_mappings.fill() 147 147 148 self.form_field_collection_wrappers = [FormFieldCollectionWrapper(field_mapping ,fields, i) 148 149 for (i,field_mapping) in self.field_mappings.items()] django/branches/per-object-permissions/django/contrib/admin/views/doc.py
r3630 r3732 329 329 views = [] 330 330 for p in urlpatterns: 331 if hasattr(p, ' get_callback'):331 if hasattr(p, '_get_callback'): 332 332 try: 333 views.append((p. get_callback(), base + p.regex.pattern))333 views.append((p._get_callback(), base + p.regex.pattern)) 334 334 except ViewDoesNotExist: 335 335 continue 336 336 elif hasattr(p, '_get_url_patterns'): 337 views.extend(extract_views_from_urlpatterns(p.url_patterns, base + p.regex.pattern)) 337 try: 338 patterns = p.url_patterns 339 except ImportError: 340 continue 341 views.extend(extract_views_from_urlpatterns(patterns, base + p.regex.pattern)) 338 342 else: 339 343 raise TypeError, _("%s does not appear to be a urlpattern object") % p django/branches/per-object-permissions/django/contrib/auth/models.py
r3682 r3732 34 34 Permissions are set globally per type of object, not per specific object instance. It is possible to say "Mary may change news stories," but it's not currently possible to say "Mary may change news stories, but only the ones she created herself" or "Mary may only change news stories that have a certain status or publication date." 35 35 36 Three basic permissions -- add, c reate and delete -- are automatically created for each Django model.36 Three basic permissions -- add, change and delete -- are automatically created for each Django model. 37 37 """ 38 38 name = models.CharField(_('name'), maxlength=50) django/branches/per-object-permissions/django/core/management.py
r3669 r3732 502 502 initial_sql = get_sql_initial_data_for_model(model) 503 503 if initial_sql: 504 print "Installing initial data for %s model" % model._meta.object_name 504 if verbosity >= 2: 505 print "Installing initial data for %s model" % model._meta.object_name 505 506 try: 506 507 for sql in initial_sql: django/branches/per-object-permissions/django/core/serializers/base.py
r3237 r3732 12 12 """Something bad happened during serialization.""" 13 13 pass 14 14 15 15 class DeserializationError(Exception): 16 16 """Something bad happened during deserialization.""" … … 21 21 Abstract serializer base class. 22 22 """ 23 23 24 24 def serialize(self, queryset, **options): 25 25 """ … … 27 27 """ 28 28 self.options = options 29 29 30 30 self.stream = options.get("stream", StringIO()) 31 31 32 32 self.start_serialization() 33 33 for obj in queryset: … … 45 45 self.end_serialization() 46 46 return self.getvalue() 47 47 48 48 def get_string_value(self, obj, field): 49 49 """ … … 51 51 """ 52 52 if isinstance(field, models.DateTimeField): 53 value = getattr(obj, field.name).strftime("%Y-%m-%d %H:%M:%S") 53 value = getattr(obj, field.name) 54 if value is None: 55 value = '' 56 else: 57 value = value.strftime("%Y-%m-%d %H:%M:%S") 54 58 elif isinstance(field, models.FileField): 55 59 value = getattr(obj, "get_%s_url" % field.name, lambda: None)() … … 57 61 value = field.flatten_data(follow=None, obj=obj).get(field.name, "") 58 62 return str(value) 59 63 60 64 def start_serialization(self): 61 65 """ … … 63 67 """ 64 68 raise NotImplementedError 65 69 66 70 def end_serialization(self): 67 71 """ … … 69 73 """ 70 74 pass 71 75 72 76 def start_object(self, obj): 73 77 """ … … 75 79 """ 76 80 raise NotImplementedError 77 81 78 82 def end_object(self, obj): 79 83 """ … … 81 85 """ 82 86 pass 83 87 84 88 def handle_field(self, obj, field): 85 89 """ … … 87 91 """ 88 92 raise NotImplementedError 89 93 90 94 def handle_fk_field(self, obj, field): 91 95 """ … … 93 97 """ 94 98 raise NotImplementedError 95 99 96 100 def handle_m2m_field(self, obj, field): 97 101 """ … … 99 103 """ 100 104 raise NotImplementedError 101 105 102 106 def getvalue(self): 103 107 """ … … 110 114 Abstract base deserializer class. 111 115 """ 112 116 113 117 def __init__(self, stream_or_string, **options): 114 118 """ … … 124 128 # and friends might fail...) 125 129 models.get_apps() 126 130 127 131 def __iter__(self): 128 132 return self 129 133 130 134 def next(self): 131 135 """Iteration iterface -- return the next item in the stream""" 132 136 raise NotImplementedError 133 137 134 138 class DeserializedObject(object): 135 139 """ 136 140 A deserialzed model. 137 141 138 142 Basically a container for holding the pre-saved deserialized data along 139 143 with the many-to-many data saved with the object. 140 144 141 145 Call ``save()`` to save the object (with the many-to-many data) to the 142 146 database; call ``save(save_m2m=False)`` to save just the object fields 143 147 (and not touch the many-to-many stuff.) 144 148 """ 145 149 146 150 def __init__(self, obj, m2m_data=None): 147 151 self.object = obj 148 152 self.m2m_data = m2m_data 149 153 150 154 def __repr__(self): 151 155 return "<DeserializedObject: %s>" % str(self.object) 152 156 153 157 def save(self, save_m2m=True): 154 158 self.object.save() … … 156 160 for accessor_name, object_list in self.m2m_data.items(): 157 161 setattr(self.object, accessor_name, object_list) 158 159 # prevent a second (possibly accidental) call to save() from saving 162 163 # prevent a second (possibly accidental) call to save() from saving 160 164 # the m2m data twice. 161 165 self.m2m_data = None django/branches/per-object-permissions/django/core/serializers/json.py
r3583 r3732 49 49 return o.strftime(self.TIME_FORMAT) 50 50 else: 51 return super( self, DateTimeAwareJSONEncoder).default(o)51 return super(DateTimeAwareJSONEncoder, self).default(o) django/branches/per-object-permissions/django/db/backends/postgresql_psycopg2/base.py
r3583 r3732 11 11 from django.core.exceptions import ImproperlyConfigured 12 12 raise ImproperlyConfigured, "Error loading psycopg2 module: %s" % e 13 14 # Register Unicode conversions15 import psycopg2.extensions16 psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)17 13 18 14 DatabaseError = Database.DatabaseError … … 48 44 self.connection.set_isolation_level(1) # make transactions transparent to all cursors 49 45 cursor = self.connection.cursor() 46 cursor.tzinfo_factory = None 50 47 cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE]) 51 48 if settings.DEBUG: … … 72 69 return '"%s"' % name 73 70 74 def dictfetchone(cursor): 75 "Returns a row from the cursor as a dict" 76 # TODO: cursor.dictfetchone() doesn't exist in psycopg2, 77 # but no Django code uses this. Safe to remove? 78 return cursor.dictfetchone() 79 80 def dictfetchmany(cursor, number): 81 "Returns a certain number of rows from a cursor as a dict" 82 # TODO: cursor.dictfetchmany() doesn't exist in psycopg2, 83 # but no Django code uses this. Safe to remove? 84 return cursor.dictfetchmany(number) 85 86 def dictfetchall(cursor): 87 "Returns all rows from a cursor as a dict" 88 # TODO: cursor.dictfetchall() doesn't exist in psycopg2, 89 # but no Django code uses this. Safe to remove? 90 return cursor.dictfetchall() 71 dictfetchone = util.dictfetchone 72 dictfetchmany = util.dictfetchmany 73 dictfetchall = util.dictfetchall 91 74 92 75 def get_last_insert_id(cursor, table_name, pk_name): django/branches/per-object-permissions/django/db/backends/sqlite3/base.py
r3115 r3732 63 63 64 64 def close(self): 65 if self.connection is not None: 65 from django.conf import settings 66 # If database is in memory, closing the connection destroys the database. 67 # To prevent accidental data loss, ignore close requests on an in-memory db. 68 if self.connection is not None and settings.DATABASE_NAME != ":memory:": 66 69 self.connection.close() 67 70 self.connection = None django/branches/per-object-permissions/django/db/backends/util.py
r3113 r3732 99 99 def _dict_helper(desc, row): 100 100 "Returns a dictionary for the given cursor.description and result row." 101 return dict( [(desc[col[0]][0], col[1]) for col in enumerate(row)])101 return dict(zip([col[0] for col in desc], row)) 102 102 103 103 def dictfetchone(cursor): django/branches/per-object-permissions/django/template/defaulttags.py
r3268 r3732 87 87 context.push() 88 88 try: 89 values = self.sequence.resolve(context )89 values = self.sequence.resolve(context, True) 90 90 except VariableDoesNotExist: 91 91 values = [] … … 213 213 214 214 def render(self, context): 215 obj_list = self.target.resolve(context )216 if obj_list == '': # target_var wasn't found in context; fail silently215 obj_list = self.target.resolve(context, True) 216 if obj_list == None: # target_var wasn't found in context; fail silently 217 217 context[self.var_name] = [] 218 218 return '' 219 219 output = [] # list of dictionaries in the format {'grouper': 'key', 'list': [list of contents]} 220 220 for obj in obj_list: 221 grouper = self.expression.resolve(Context({'var': obj}) )221 grouper = self.expression.resolve(Context({'var': obj}), True) 222 222 # TODO: Is this a sensible way to determine equality? 223 223 if output and repr(output[-1]['grouper']) == repr(grouper): … … 252 252 if self.parsed: 253 253 try: 254 t = Template(output )254 t = Template(output, name=self.filepath) 255 255 return t.render(context) 256 256 except TemplateSyntaxError, e: django/branches/per-object-permissions/django/template/__init__.py
r3464 r3732 138 138 139 139 class Template(object): 140 def __init__(self, template_string, origin=None ):140 def __init__(self, template_string, origin=None, name='<Unknown Template>'): 141 141 "Compilation stage" 142 142 if settings.TEMPLATE_DEBUG and origin == None: … … 145 145 # came from... 146 146 self.nodelist = compile_string(template_string, origin) 147 self.name = name 147 148 148 149 def __iter__(self): … … 435 436 i += 1 436 437 if i >= len(subject): 437 raise TemplateSyntaxError, "Searching for value. Unexpected end of string in column %d: %s" % subject438 raise TemplateSyntaxError, "Searching for value. Unexpected end of string in column %d: %s" % (i, subject) 438 439 i += 1 439 440 res = subject[p:i] … … 549 550 except VariableDoesNotExist: 550 551 if ignore_failures: 551 returnNone552 obj = None 552 553 else: 553 return settings.TEMPLATE_STRING_IF_INVALID 554 if settings.TEMPLATE_STRING_IF_INVALID: 555 return settings.TEMPLATE_STRING_IF_INVALID 556 else: 557 obj = settings.TEMPLATE_STRING_IF_INVALID 554 558 for func, args in self.filters: 555 559 arg_vals = [] … … 615 619 (The example assumes VARIABLE_ATTRIBUTE_SEPARATOR is '.') 616 620 """ 617 if path == 'False': 618 current = False 619 elif path == 'True': 620 current = True 621 elif path[0].isdigit(): 621 if path[0].isdigit(): 622 622 number_type = '.' in path and float or int 623 623 try: django/branches/per-object-permissions/django/template/loader.py
r3464 r3732 77 77 handling template inheritance recursively. 78 78 """ 79 return get_template_from_string(*find_template_source(template_name)) 79 source, origin = find_template_source(template_name) 80 template = get_template_from_string(source, origin, template_name) 81 return template 80 82 81 def get_template_from_string(source, origin=None ):83 def get_template_from_string(source, origin=None, name=None): 82 84 """ 83 85 Returns a compiled Template object for the given template code, 84 86 handling template inheritance recursively. 85 87 """ 86 return Template(source, origin )88 return Template(source, origin, name) 87 89 88 90 def render_to_string(template_name, dictionary=None, context_instance=None): django/branches/per-object-permissions/django/template/loader_tags.py
r3583 r3732 52 52 raise TemplateSyntaxError, error_msg 53 53 if hasattr(parent, 'render'): 54 return parent 54 return parent # parent is a Template object 55 55 try: 56 56 source, origin = find_template_source(parent, self.template_dirs) … … 58 58 raise TemplateSyntaxError, "Template %r cannot be extended, because it doesn't exist" % parent 59 59 else: 60 return get_template_from_string(source, origin )60 return get_template_from_string(source, origin, parent) 61 61 62 62 def render(self, context): django/branches/per-object-permissions/django/test/client.py
r3669 r3732 1 1 from cStringIO import StringIO 2 from django.contrib.admin.views.decorators import LOGIN_FORM_KEY, _encode_post_data3 2 from django.core.handlers.base import BaseHandler 4 3 from django.core.handlers.wsgi import WSGIRequest 5 4 from django.dispatch import dispatcher 6 5 from django.http import urlencode, SimpleCookie 7 from django.te mplateimport signals6 from django.test import signals 8 7 from django.utils.functional import curry 9 8 … … 97 96 """ 98 97 def __init__(self, **defaults): 99 self.handler = TestHandler()98 self.handler = ClientHandler() 100 99 self.defaults = defaults 101 100 self.cookie = SimpleCookie() … … 127 126 on_template_render = curry(store_rendered_templates, data) 128 127 dispatcher.connect(on_template_render, signal=signals.template_rendered) 129 128 130 129 response = self.handler(environ) 131 130 … … 181 180 """ 182 181 A specialized sequence of GET and POST to log into a view that 183 is protected by @login_required or a similaraccess decorator.184 185 path should be the URL of the login page, or of any page that186 is login protected.187 188 Returns True if login was successful; False if otherwise.189 """ 190 # First, GET the login page.191 # This is required to establish the session.182 is protected by a @login_required access decorator. 183 184 path should be the URL of the page that is login protected. 185 186 Returns the response from GETting the requested URL after 187 login is complete. Returns False if login process failed. 188 """ 189 # First, GET the page that is login protected. 190 # This page will redirect to the login page. 192 191 response = self.get(path) 192 if response.status_code != 302: 193 return False 194 195 login_path, data = response['Location'].split('?') 196 next = data.split('=')[1] 197 198 # Second, GET the login page; required to set up cookies 199 response = self.get(login_path, **extra) 193 200 if response.status_code != 200: 194 201 return False 195 196 # Set up the block of form data required by the login page.202 203 # Last, POST the login data. 197 204 form_data = { 198 205 'username': username, 199 206 'password': password, 200 'this_is_the_login_form': 1, 201 'post_data': _encode_post_data({LOGIN_FORM_KEY: 1}) 207 'next' : next, 202 208 } 203 response = self.post(path, data=form_data, **extra) 204 205 # login page should give response 200 (if you requested the login 206 # page specifically), or 302 (if you requested a login 207 # protected page, to which the login can redirect). 208 return response.status_code in (200,302) 209 response = self.post(login_path, data=form_data, **extra) 210 211 # Login page should 302 redirect to the originally requested page 212 if response.status_code != 302 or response['Location'] != path: 213 return False 214 215 # Since we are logged in, request the actual page again 216 return self.get(path) django/branches/per-object-permissions/django/test/simple.py
r3669 r3732 2 2 from django.conf import settings 3 3 from django.core import management 4 from django.test.utils import setup_test_environment, teardown_test_environment 4 5 from django.test.utils import create_test_db, destroy_test_db 5 6 from django.test.testcases import OutputChecker, DocTestRunner … … 52 53 will be added to the test suite. 53 54 """ 55 setup_test_environment() 54 56 55 57 settings.DEBUG = False … … 62 64 suite.addTest(test) 63 65 64 old_name = create_test_db(verbosity) 66 old_name = settings.DATABASE_NAME 67 create_test_db(verbosity) 65 68 management.syncdb(verbosity, interactive=False) 66 69 unittest.TextTestRunner(verbosity=verbosity).run(suite) 67 70 destroy_test_db(old_name, verbosity) 71 72 teardown_test_environment() django/branches/per-object-permissions/django/test/utils.py
r3669 r3732 1 1 import sys, time 2 2 from django.conf import settings 3 from django.db import connection, transaction 3 from django.db import connection, transaction, backend 4 from django.dispatch import dispatcher 5 from django.test import signals 6 from django.template import Template 4 7 5 8 # The prefix to put on the default database name when creating … … 7 10 TEST_DATABASE_PREFIX = 'test_' 8 11 12 def instrumented_test_render(self, context): 13 """An instrumented Template render method, providing a signal 14 that can be intercepted by the test system Client 15 16 """ 17 dispatcher.send(signal=signals.template_rendered, sender=self, template=self, context=context) 18 return self.nodelist.render(context) 19 20 def setup_test_environment(): 21 """Perform any global pre-test setup. This involves: 22 23 - Installing the instrumented test renderer 24 25 """ 26 Template.original_render = Template.render 27 Template.render = instrumented_test_render 28 29 def teardown_test_environment(): 30 """Perform any global post-test teardown. This involves: 31 32 - Restoring the original test renderer 33 34 """ 35 Template.render = Template.original_render 36 del Template.original_render 37 9 38 def _set_autocommit(connection): 10 39 "Make sure a connection is in autocommit mode." … … 22 51 TEST_DATABASE_NAME = ":memory:" 23 52 else: 24 TEST_DATABASE_NAME = TEST_DATABASE_PREFIX + settings.DATABASE_NAME 53 if settings.TEST_DATABASE_NAME: 54 TEST_DATABASE_NAME = settings.TEST_DATABASE_NAME 55 else: 56 TEST_DATABASE_NAME = TEST_DATABASE_PREFIX + settings.DATABASE_NAME 25 57 26 58 # Create the test database and connect to it. We need to autocommit … … 30 62 _set_autocommit(connection) 31 63 try: 32 cursor.execute("CREATE DATABASE %s" % TEST_DATABASE_NAME)64 cursor.execute("CREATE DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME)) 33 65 except Exception, e: 34 66 sys.stderr.write("Got an error creating the test database: %s\n" % e) … … 39 71 if verbosity >= 1: 40 72 print "Destroying old test database..." 41 cursor.execute("DROP DATABASE %s" % TEST_DATABASE_NAME)73 cursor.execute("DROP DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME)) 42 74 if verbosity >= 1: 43 75 print "Creating test database..." 44 cursor.execute("CREATE DATABASE %s" % TEST_DATABASE_NAME)76 cursor.execute("CREATE DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME)) 45 77 except Exception, e: 46 78 sys.stderr.write("Got an error recreating the test database: %s\n" % e) … … 51 83 52 84 connection.close() 53 old_database_name = settings.DATABASE_NAME54 85 settings.DATABASE_NAME = TEST_DATABASE_NAME 55 86 … … 57 88 # the side effect of initializing the test database. 58 89 cursor = connection.cursor() 59 60 return old_database_name61 90 62 91 def destroy_test_db(old_database_name, verbosity=1): … … 67 96 if verbosity >= 1: 68 97 print "Destroying test database..." 98 connection.close() 99 TEST_DATABASE_NAME = settings.DATABASE_NAME 100 settings.DATABASE_NAME = old_database_name 101 69 102 if settings.DATABASE_ENGINE != "sqlite3": 70 connection.close()71 TEST_DATABASE_NAME = settings.DATABASE_NAME72 settings.DATABASE_NAME = old_database_name73 103 cursor = connection.cursor() 74 104 _set_autocommit(connection) 75 105 time.sleep(1) # To avoid "database is being accessed by other users" errors. 76 cursor.execute("DROP DATABASE %s" % TEST_DATABASE_NAME)106 cursor.execute("DROP DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME)) 77 107 connection.close() 78 django/branches/per-object-permissions/django/utils/datastructures.py
r3113 r3732 188 188 &nbs
