diff options
| author | Jason Pellerin <jpellerin@gmail.com> | 2006-08-14 01:03:32 +0000 |
|---|---|---|
| committer | Jason Pellerin <jpellerin@gmail.com> | 2006-08-14 01:03:32 +0000 |
| commit | bec235deefbca44d1a9f3b95e453d946b1359135 (patch) | |
| tree | df09c2bada8a5583800a178a514fe6ba13241bd7 /django | |
| parent | 238c6ecd5b10c6c76b8b1db03dcb746bcfe366af (diff) | |
[multi-db] Merge trunk to [3578]
git-svn-id: http://code.djangoproject.com/svn/django/branches/multiple-db-support@3581 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django')
24 files changed, 132 insertions, 82 deletions
diff --git a/django/bin/compile-messages.py b/django/bin/compile-messages.py index 5f653df95d..44a84de379 100755 --- a/django/bin/compile-messages.py +++ b/django/bin/compile-messages.py @@ -14,7 +14,7 @@ def compile_messages(): print "this script should be run from the django svn tree or your project or app tree" sys.exit(1) - for (dirpath, dirnames, filenames) in os.walk(basedir): + for dirpath, dirnames, filenames in os.walk(basedir): for f in filenames: if f.endswith('.po'): sys.stderr.write('processing file %s in %s\n' % (f, dirpath)) diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py index 3d203d97de..25bafbdce9 100644 --- a/django/conf/global_settings.py +++ b/django/conf/global_settings.py @@ -255,6 +255,7 @@ MIDDLEWARE_CLASSES = ( SESSION_COOKIE_NAME = 'sessionid' # Cookie name. This can be whatever you want. SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2 # Age of cookie, in seconds (default: 2 weeks). SESSION_COOKIE_DOMAIN = None # A string like ".lawrence.com", or None for standard domain cookie. +SESSION_COOKIE_SECURE = False # Whether the session cookie should be secure (https:// only). SESSION_SAVE_EVERY_REQUEST = False # Whether to save the session data on every request. SESSION_EXPIRE_AT_BROWSER_CLOSE = False # Whether sessions expire when a user closes his browser. diff --git a/django/conf/project_template/settings.py b/django/conf/project_template/settings.py index 14da715db5..63e07c061a 100644 --- a/django/conf/project_template/settings.py +++ b/django/conf/project_template/settings.py @@ -60,8 +60,9 @@ MIDDLEWARE_CLASSES = ( ROOT_URLCONF = '{{ project_name }}.urls' TEMPLATE_DIRS = ( - # Put strings here, like "/home/html/django_templates". + # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Always use forward slashes, even on Windows. + # Don't forget to use absolute paths, not relative paths. ) INSTALLED_APPS = ( diff --git a/django/contrib/admin/templates/admin/change_form.html b/django/contrib/admin/templates/admin/change_form.html index e61eb5513b..b1fdc5ebdb 100644 --- a/django/contrib/admin/templates/admin/change_form.html +++ b/django/contrib/admin/templates/admin/change_form.html @@ -21,7 +21,7 @@ {% if has_absolute_url %}<li><a href="../../../r/{{ content_type_id }}/{{ object_id }}/" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif%} </ul> {% endif %}{% endif %} -<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post">{% block form_top %}{% endblock %} +<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.module_name }}_form">{% block form_top %}{% endblock %} <div> {% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %} {% if opts.admin.save_on_top %}{% submit_row %}{% endif %} diff --git a/django/contrib/admin/templates/admin/edit_inline_tabular.html b/django/contrib/admin/templates/admin/edit_inline_tabular.html index 13d528331b..3d059c8b3d 100644 --- a/django/contrib/admin/templates/admin/edit_inline_tabular.html +++ b/django/contrib/admin/templates/admin/edit_inline_tabular.html @@ -7,6 +7,7 @@ <th{{ fw.header_class_attribute }}>{{ fw.field.verbose_name|capfirst|escape }}</th> {% endif %} {% endfor %} + </tr></thead> {% for fcw in bound_related_object.form_field_collection_wrappers %} {% if change %}{% if original_row_needed %} {% if fcw.obj.original %} diff --git a/django/contrib/admin/urls.py b/django/contrib/admin/urls.py index 88cf8306a3..aaf9841e45 100644 --- a/django/contrib/admin/urls.py +++ b/django/contrib/admin/urls.py @@ -21,7 +21,6 @@ urlpatterns = patterns('', ('^doc/tags/$', 'django.contrib.admin.views.doc.template_tag_index'), ('^doc/filters/$', 'django.contrib.admin.views.doc.template_filter_index'), ('^doc/views/$', 'django.contrib.admin.views.doc.view_index'), - ('^doc/views/jump/$', 'django.contrib.admin.views.doc.jump_to_view'), ('^doc/views/(?P<view>[^/]+)/$', 'django.contrib.admin.views.doc.view_detail'), ('^doc/models/$', 'django.contrib.admin.views.doc.model_index'), ('^doc/models/(?P<app_label>[^\.]+)\.(?P<model_name>[^/]+)/$', 'django.contrib.admin.views.doc.model_detail'), diff --git a/django/contrib/admin/views/doc.py b/django/contrib/admin/views/doc.py index 68799fcc17..d1541abee9 100644 --- a/django/contrib/admin/views/doc.py +++ b/django/contrib/admin/views/doc.py @@ -43,11 +43,11 @@ def template_tag_index(request): for tag_name, tag_func in library.tags.items(): title, body, metadata = utils.parse_docstring(tag_func.__doc__) if title: - title = utils.parse_rst(title, 'tag', 'tag:' + tag_name) + title = utils.parse_rst(title, 'tag', _('tag:') + tag_name) if body: - body = utils.parse_rst(body, 'tag', 'tag:' + tag_name) + body = utils.parse_rst(body, 'tag', _('tag:') + tag_name) for key in metadata: - metadata[key] = utils.parse_rst(metadata[key], 'tag', 'tag:' + tag_name) + metadata[key] = utils.parse_rst(metadata[key], 'tag', _('tag:') + tag_name) if library in template.builtins: tag_library = None else: @@ -74,11 +74,11 @@ def template_filter_index(request): for filter_name, filter_func in library.filters.items(): title, body, metadata = utils.parse_docstring(filter_func.__doc__) if title: - title = utils.parse_rst(title, 'filter', 'filter:' + filter_name) + title = utils.parse_rst(title, 'filter', _('filter:') + filter_name) if body: - body = utils.parse_rst(body, 'filter', 'filter:' + filter_name) + body = utils.parse_rst(body, 'filter', _('filter:') + filter_name) for key in metadata: - metadata[key] = utils.parse_rst(metadata[key], 'filter', 'filter:' + filter_name) + metadata[key] = utils.parse_rst(metadata[key], 'filter', _('filter:') + filter_name) if library in template.builtins: tag_library = None else: @@ -132,11 +132,11 @@ def view_detail(request, view): raise Http404 title, body, metadata = utils.parse_docstring(view_func.__doc__) if title: - title = utils.parse_rst(title, 'view', 'view:' + view) + title = utils.parse_rst(title, 'view', _('view:') + view) if body: - body = utils.parse_rst(body, 'view', 'view:' + view) + body = utils.parse_rst(body, 'view', _('view:') + view) for key in metadata: - metadata[key] = utils.parse_rst(metadata[key], 'model', 'view:' + view) + metadata[key] = utils.parse_rst(metadata[key], 'model', _('view:') + view) return render_to_response('admin_doc/view_detail.html', { 'name': view, 'summary': title, @@ -161,14 +161,14 @@ def model_detail(request, app_label, model_name): try: app_mod = models.get_app(app_label) except ImproperlyConfigured: - raise Http404, "App %r not found" % app_label + raise Http404, _("App %r not found") % app_label model = None for m in models.get_models(app_mod): if m._meta.object_name.lower() == model_name: model = m break if model is None: - raise Http404, "Model %r not found in app %r" % (model_name, app_label) + raise Http404, _("Model %r not found in app %r") % (model_name, app_label) opts = model._meta @@ -180,7 +180,7 @@ def model_detail(request, app_label, model_name): if isinstance(field, models.ForeignKey): data_type = related_object_name = field.rel.to.__name__ app_label = field.rel.to._meta.app_label - verbose = utils.parse_rst(("the related `%s.%s` object" % (app_label, data_type)), 'model', 'model:' + data_type) + verbose = utils.parse_rst((_("the related `%s.%s` object") % (app_label, data_type)), 'model', _('model:') + data_type) else: data_type = get_readable_field_data_type(field) verbose = field.verbose_name @@ -202,7 +202,7 @@ def model_detail(request, app_label, model_name): continue verbose = func.__doc__ if verbose: - verbose = utils.parse_rst(utils.trim_docstring(verbose), 'model', 'model:' + opts.module_name) + verbose = utils.parse_rst(utils.trim_docstring(verbose), 'model', _('model:') + opts.module_name) fields.append({ 'name': func_name, 'data_type': get_return_data_type(func_name), @@ -211,17 +211,17 @@ def model_detail(request, app_label, model_name): # Gather related objects for rel in opts.get_all_related_objects(): - verbose = "related `%s.%s` objects" % (rel.opts.app_label, rel.opts.object_name) + verbose = _("related `%s.%s` objects") % (rel.opts.app_label, rel.opts.object_name) accessor = rel.get_accessor_name() fields.append({ 'name' : "%s.all" % accessor, 'data_type' : 'List', - 'verbose' : utils.parse_rst("all " + verbose , 'model', 'model:' + opts.module_name), + 'verbose' : utils.parse_rst(_("all %s") % verbose , 'model', _('model:') + opts.module_name), }) fields.append({ 'name' : "%s.count" % accessor, 'data_type' : 'Integer', - 'verbose' : utils.parse_rst("number of " + verbose , 'model', 'model:' + opts.module_name), + 'verbose' : utils.parse_rst(_("number of %s") % verbose , 'model', _('model:') + opts.module_name), }) return render_to_response('admin_doc/model_detail.html', { @@ -336,7 +336,7 @@ def extract_views_from_urlpatterns(urlpatterns, base=''): elif hasattr(p, '_get_url_patterns'): views.extend(extract_views_from_urlpatterns(p.url_patterns, base + p.regex.pattern)) else: - raise TypeError, "%s does not appear to be a urlpattern object" % p + raise TypeError, _("%s does not appear to be a urlpattern object") % p return views named_group_matcher = re.compile(r'\(\?P(<\w+>).+?\)') diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 705dfad6c8..0f6167fc8f 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -263,7 +263,7 @@ def add_stage(request, app_label, model_name, show_delete=False, form_url='', po post_url_continue += "?_popup=1" return HttpResponseRedirect(post_url_continue % pk_value) if request.POST.has_key("_popup"): - return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %s, "%s");</script>' % \ + return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %r, "%s");</script>' % \ (pk_value, str(new_object).replace('"', '\\"'))) elif request.POST.has_key("_addanother"): request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name)) diff --git a/django/contrib/flatpages/README.TXT b/django/contrib/flatpages/README.TXT index e46aa1f9bf..d3071377f5 100644 --- a/django/contrib/flatpages/README.TXT +++ b/django/contrib/flatpages/README.TXT @@ -2,7 +2,7 @@ This is an optional add-on app, flatpages. For full documentation, see either of these: - * The file django/docs/flatpages.txt in the Django distribution + * The file docs/flatpages.txt in the Django distribution * http://www.djangoproject.com/documentation/flatpages/ on the Web -Both have identical content.
\ No newline at end of file +Both have identical content. diff --git a/django/contrib/sessions/middleware.py b/django/contrib/sessions/middleware.py index dde4f1a6c0..2337ad8a61 100644 --- a/django/contrib/sessions/middleware.py +++ b/django/contrib/sessions/middleware.py @@ -88,5 +88,6 @@ class SessionMiddleware(object): new_session = Session.objects.save(session_key, request.session._session, datetime.datetime.now() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE)) response.set_cookie(settings.SESSION_COOKIE_NAME, session_key, - max_age=max_age, expires=expires, domain=settings.SESSION_COOKIE_DOMAIN) + max_age=max_age, expires=expires, domain=settings.SESSION_COOKIE_DOMAIN, + secure=settings.SESSION_COOKIE_SECURE or None) return response diff --git a/django/core/management.py b/django/core/management.py index c910c15589..e315b20674 100644 --- a/django/core/management.py +++ b/django/core/management.py @@ -110,9 +110,14 @@ def get_sql_create(app): sys.exit(1) # Get installed models, so we generate REFERENCES right + # We trim models from the current app so that the sqlreset command does + # not generate invalid SQL (leaving models out of known_models is + # harmless, so we can be conservative). manager = model._default_manager tables = manager.get_table_list() - installed_models = manager.get_installed_models(tables) + installed_models = [ model for model in + manager.get_installed_models(tables) + if model not in app_models ] models_output = set(installed_models) builder = creation.builder builder.models_already_seen.update(models_output) @@ -136,11 +141,14 @@ def get_sql_create(app): # but don't exist physically not_installed_models = set(pending_references.keys()) if not_installed_models: - final_output.append('-- The following references should be added but depend on non-existant tables:') + alter_sql = [] for model in not_installed_models: - final_output.extend(['-- ' + sql - for sql in pending_references.pop(model)]) - + alter_sql.extend(['-- ' + sql + for sql in pending_references.pop(model)]) + if alter_sql: + final_output.append('-- The following references should be added ' + 'but depend on non-existent tables:') + final_output.extend(alter_sql) # convert BoundStatements into strings final_output = map(str, final_output) return final_output @@ -563,9 +571,7 @@ def inspectdb(): introspection_module = get_introspection_module() - def table2model(table_name): - object_name = table_name.title().replace('_', '') - return object_name.endswith('s') and object_name[:-1] or object_name + table2model = lambda table_name: table_name.title().replace('_', '') cursor = connection.cursor() yield "# This is an auto-generated Django model module." @@ -594,6 +600,10 @@ def inspectdb(): comment_notes = [] # Holds Field notes, to be displayed in a Python comment. extra_params = {} # Holds Field parameters such as 'db_column'. + if ' ' in att_name: + extra_params['db_column'] = att_name + att_name = att_name.replace(' ', '') + comment_notes.append('Field renamed to remove spaces.') if keyword.iskeyword(att_name): extra_params['db_column'] = att_name att_name += '_field' @@ -1010,7 +1020,14 @@ def dbshell(): dbshell.args = "" def runfcgi(args): - """Run this project as a FastCGI application. requires flup.""" + "Runs this project as a FastCGI application. Requires flup." + from django.conf import settings + from django.utils import translation + # Activate the current language, because it won't get activated later. + try: + translation.activate(settings.LANGUAGE_CODE) + except AttributeError: + pass from django.core.servers.fastcgi import runfastcgi runfastcgi(args) runfcgi.args = '[various KEY=val options, use `runfcgi help` for help]' @@ -1167,7 +1184,11 @@ def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING, argv=None): if action not in NO_SQL_TRANSACTION: print style.SQL_KEYWORD("COMMIT;") -def execute_manager(settings_mod, argv=None): +def setup_environ(settings_mod): + """ + Configure the runtime environment. This can also be used by external + scripts wanting to set up a similar environment to manage.py. + """ # Add this project to sys.path so that it's importable in the conventional # way. For example, if this file (manage.py) lives in a directory # "myproject", this code would add "/path/to/myproject" to sys.path. @@ -1179,7 +1200,10 @@ def execute_manager(settings_mod, argv=None): # Set DJANGO_SETTINGS_MODULE appropriately. os.environ['DJANGO_SETTINGS_MODULE'] = '%s.settings' % project_name + return project_directory +def execute_manager(settings_mod, argv=None): + project_directory = setup_environ(settings_mod) action_mapping = DEFAULT_ACTION_MAPPING.copy() # Remove the "startproject" command from the action_mapping, because that's diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py index 7ce5706c23..4bd0e50e53 100644 --- a/django/core/servers/basehttp.py +++ b/django/core/servers/basehttp.py @@ -547,10 +547,6 @@ class WSGIRequestHandler(BaseHTTPRequestHandler): env['PATH_INFO'] = urllib.unquote(path) env['QUERY_STRING'] = query - - host = self.address_string() - if host != self.client_address[0]: - env['REMOTE_HOST'] = host env['REMOTE_ADDR'] = self.client_address[0] if self.headers.typeheader is None: diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py index 1da25c9f83..2f557b90a6 100644 --- a/django/core/urlresolvers.py +++ b/django/core/urlresolvers.py @@ -86,10 +86,15 @@ class MatchChecker(object): class RegexURLPattern(object): def __init__(self, regex, callback, default_args=None): # regex is a string representing a regular expression. - # callback is something like 'foo.views.news.stories.story_detail', - # which represents the path to a module and a view function name. + # callback is either a string like 'foo.views.news.stories.story_detail' + # which represents the path to a module and a view function name, or a + # callable object (view). self.regex = re.compile(regex) - self.callback = callback + if callable(callback): + self._callback = callback + else: + self._callback = None + self._callback_str = callback self.default_args = default_args or {} def resolve(self, path): @@ -106,23 +111,28 @@ class RegexURLPattern(object): # In both cases, pass any extra_kwargs as **kwargs. kwargs.update(self.default_args) - try: # Lazily load self.func. - return self.func, args, kwargs - except AttributeError: - self.func = self.get_callback() - return self.func, args, kwargs + return self.callback, args, kwargs - def get_callback(self): - mod_name, func_name = get_mod_func(self.callback) + def _get_callback(self): + if self._callback is not None: + return self._callback + mod_name, func_name = get_mod_func(self._callback_str) try: - return getattr(__import__(mod_name, '', '', ['']), func_name) + self._callback = getattr(__import__(mod_name, '', '', ['']), func_name) except ImportError, e: raise ViewDoesNotExist, "Could not import %s. Error was: %s" % (mod_name, str(e)) except AttributeError, e: raise ViewDoesNotExist, "Tried %s in module %s. Error was: %s" % (func_name, mod_name, str(e)) + return self._callback + callback = property(_get_callback) def reverse(self, viewname, *args, **kwargs): - if viewname != self.callback: + mod_name, func_name = get_mod_func(viewname) + try: + lookup_view = getattr(__import__(mod_name, '', '', ['']), func_name) + except (ImportError, AttributeError): + raise NoReverseMatch + if lookup_view != self.callback: raise NoReverseMatch return self.reverse_helper(*args, **kwargs) @@ -185,22 +195,28 @@ class RegexURLResolver(object): def resolve500(self): return self._resolve_special('500') - def reverse(self, viewname, *args, **kwargs): + def reverse(self, lookup_view, *args, **kwargs): + if not callable(lookup_view): + mod_name, func_name = get_mod_func(lookup_view) + try: + lookup_view = getattr(__import__(mod_name, '', '', ['']), func_name) + except (ImportError, AttributeError): + raise NoReverseMatch for pattern in self.urlconf_module.urlpatterns: if isinstance(pattern, RegexURLResolver): try: - return pattern.reverse_helper(viewname, *args, **kwargs) + return pattern.reverse_helper(lookup_view, *args, **kwargs) except NoReverseMatch: continue - elif pattern.callback == viewname: + elif pattern.callback == lookup_view: try: return pattern.reverse_helper(*args, **kwargs) except NoReverseMatch: continue raise NoReverseMatch - def reverse_helper(self, viewname, *args, **kwargs): - sub_match = self.reverse(viewname, *args, **kwargs) + def reverse_helper(self, lookup_view, *args, **kwargs): + sub_match = self.reverse(lookup_view, *args, **kwargs) result = reverse_helper(self.regex, *args, **kwargs) return result + sub_match diff --git a/django/db/backends/ansi/sql.py b/django/db/backends/ansi/sql.py index 70928d3560..6298749b1d 100644 --- a/django/db/backends/ansi/sql.py +++ b/django/db/backends/ansi/sql.py @@ -139,7 +139,7 @@ class SchemaBuilder(object): col = opts.get_field(f.rel.field_name).column # For MySQL, r_name must be unique in the first 64 # characters. So we are careful with character usage here. - r_name = '%s_refs_%s_%x' % (r_col, col, + r_name = '%s_refs_%s_%x' % (col, r_col, abs(hash((r_table, table)))) sql = style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s);' % \ (quote_name(table), quote_name(r_name), @@ -262,8 +262,10 @@ class SchemaBuilder(object): style.SQL_TABLE(qn(table)), style.SQL_KEYWORD( backend.get_drop_foreignkey_sql()), - style.SQL_FIELD(qn("%s_referencing_%s_%s" % - (col, r_table, r_col)))), + style.SQL_FIELD(qn("%s_refs_%s_%x" % + (col, r_col, + abs(hash((table, r_table))))) + )), db.connection)) del references_to_delete[model] # many to many: drop any many-many tables that are my diff --git a/django/db/backends/postgresql_psycopg2/base.py b/django/db/backends/postgresql_psycopg2/base.py index adfc1d1762..308bc12aa8 100644 --- a/django/db/backends/postgresql_psycopg2/base.py +++ b/django/db/backends/postgresql_psycopg2/base.py @@ -11,6 +11,10 @@ except ImportError, e: from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured, "Error loading psycopg2 module: %s" % e +# Register Unicode conversions +import psycopg2.extensions +psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) + DatabaseError = Database.DatabaseError try: diff --git a/django/db/models/__init__.py b/django/db/models/__init__.py index 54df38cc7b..0308dd047a 100644 --- a/django/db/models/__init__.py +++ b/django/db/models/__init__.py @@ -25,7 +25,7 @@ def permalink(func): def inner(*args, **kwargs): bits = func(*args, **kwargs) viewname = bits[0] - return reverse(bits[0], None, *bits[1:2]) + return reverse(bits[0], None, *bits[1:3]) return inner class LazyDate(object): @@ -47,7 +47,7 @@ class LazyDate(object): return "<LazyDate: %s>" % self.delta def __get_value__(self): - return datetime.datetime.now() + self.delta + return (datetime.datetime.now() + self.delta).date() def __getattr__(self, attr): return getattr(self.__get_value__(), attr) diff --git a/django/db/models/base.py b/django/db/models/base.py index 7cde8f944c..da957efc2c 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -180,11 +180,12 @@ class Model(object): # If it does already exist, do an UPDATE. if cursor.fetchone(): db_values = [f.get_db_prep_save(f.pre_save(self, False)) for f in non_pks] - cursor.execute("UPDATE %s SET %s WHERE %s=%%s" % \ - (qn(self._meta.db_table), - ','.join(['%s=%%s' % qn(f.column) for f in non_pks]), - qn(self._meta.pk.column)), - db_values + [pk_val]) + if db_values: + cursor.execute("UPDATE %s SET %s WHERE %s=%%s" % \ + (qn(self._meta.db_table), + ','.join(['%s=%%s' % qn(f.column) for f in non_pks]), + qn(self._meta.pk.column)), + db_values + [pk_val]) else: record_exists = False if not pk_set or not record_exists: diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 35c0f375a1..1c85b5b68a 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -20,7 +20,7 @@ BLANK_CHOICE_DASH = [("", "---------")] BLANK_CHOICE_NONE = [("", "None")] # prepares a value for use in a LIKE query -prep_for_like_query = lambda x: str(x).replace("%", "\%").replace("_", "\_") +prep_for_like_query = lambda x: str(x).replace("\\", "\\\\").replace("%", "\%").replace("_", "\_") # returns the <ul> class for a given radio_admin value get_ul_class = lambda x: 'radiolist%s' % ((x == HORIZONTAL) and ' inline' or '') diff --git a/django/db/models/loading.py b/django/db/models/loading.py index 123436cf60..76952401d5 100644 --- a/django/db/models/loading.py +++ b/django/db/models/loading.py @@ -35,7 +35,7 @@ def get_apps(): _app_errors[app_name] = e return _app_list -def get_app(app_label, emptyOK = False): +def get_app(app_label, emptyOK=False): "Returns the module containing the models for the given app_label. If the app has no models in it and 'emptyOK' is True, returns None." get_apps() # Run get_apps() to populate the _app_list cache. Slightly hackish. for app_name in settings.INSTALLED_APPS: @@ -83,7 +83,7 @@ def get_models(app_mod=None, creation_order=False): model_list.extend(get_models(app_mod)) return model_list -def get_model(app_label, model_name, seed_cache = True): +def get_model(app_label, model_name, seed_cache=True): """ Returns the model matching the given app_label and case-insensitive model_name. diff --git a/django/db/models/manipulators.py b/django/db/models/manipulators.py index 69e13dd160..b0ce48dec5 100644 --- a/django/db/models/manipulators.py +++ b/django/db/models/manipulators.py @@ -138,7 +138,7 @@ class AutomaticManipulator(forms.Manipulator): child_follow = self.follow.get(related.name, None) if child_follow: - obj_list = expanded_data[related.var_name].items() + obj_list = expanded_data.get(related.var_name, {}).items() if not obj_list: continue diff --git a/django/http/__init__.py b/django/http/__init__.py index 06f6a106ee..c4ac302ec5 100644 --- a/django/http/__init__.py +++ b/django/http/__init__.py @@ -38,7 +38,7 @@ class HttpRequest(object): def get_full_path(self): return '' - + def is_secure(self): return os.environ.get("HTTPS") == "on" @@ -203,11 +203,14 @@ class HttpResponse(object): if val is not None: self.cookies[key][var.replace('_', '-')] = val - def delete_cookie(self, key): - try: - self.cookies[key]['max_age'] = 0 - except KeyError: - pass + def delete_cookie(self, key, path='/', domain=None): + self.cookies[key] = '' + if path is not None: + self.cookies[key]['path'] = path + if domain is not None: + self.cookies[key]['domain'] = path + self.cookies[key]['expires'] = 0 + self.cookies[key]['max-age'] = 0 def _get_content(self): content = ''.join(self._iterator) diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py index c75f371ec8..a2e9d2f405 100644 --- a/django/template/defaultfilters.py +++ b/django/template/defaultfilters.py @@ -339,7 +339,7 @@ def date(value, arg=None): def time(value, arg=None): "Formats a time according to the given format" from django.utils.dateformat import time_format - if not value: + if value in (None, ''): return '' if arg is None: arg = settings.TIME_FORMAT @@ -437,7 +437,7 @@ def pluralize(value, arg='s'): is used instead. If the provided argument contains a comma, the text before the comma is used for the singular case. """ - if not ',' in arg: + if not ',' in arg: arg = ',' + arg bits = arg.split(',') if len(bits) > 2: diff --git a/django/template/loaders/filesystem.py b/django/template/loaders/filesystem.py index 0c94021fb8..d01f54c5fe 100644 --- a/django/template/loaders/filesystem.py +++ b/django/template/loaders/filesystem.py @@ -17,7 +17,7 @@ def load_template_source(template_name, template_dirs=None): return (open(filepath).read(), filepath) except IOError: tried.append(filepath) - if template_dirs: + if tried: error_msg = "Tried %s" % tried else: error_msg = "Your TEMPLATE_DIRS setting is empty. Change it to point to at least one template directory." diff --git a/django/views/generic/create_update.py b/django/views/generic/create_update.py index 27ba327ff5..034253a549 100644 --- a/django/views/generic/create_update.py +++ b/django/views/generic/create_update.py @@ -6,6 +6,7 @@ from django.contrib.auth.views import redirect_to_login from django.template import RequestContext from django.http import Http404, HttpResponse, HttpResponseRedirect from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured +from django.utils.translation import gettext def create_object(request, model, template_name=None, template_loader=loader, extra_context=None, post_save_redirect=None, @@ -39,7 +40,7 @@ def create_object(request, model, template_name=None, new_object = manipulator.save(new_data) if request.user.is_authenticated(): - request.user.message_set.create(message="The %s was created successfully." % model._meta.verbose_name) + request.user.message_set.create(message=gettext("The %(verbose_name)s was created successfully.") % {"verbose_name": model._meta.verbose_name}) # Redirect to the new object: first by trying post_save_redirect, # then by obj.get_absolute_url; fail if neither works. @@ -113,7 +114,7 @@ def update_object(request, model, object_id=None, slug=None, object = manipulator.save(new_data) if request.user.is_authenticated(): - request.user.message_set.create(message="The %s was updated successfully." % model._meta.verbose_name) + request.user.message_set.create(message=gettext("The %(verbose_name)s was updated successfully.") % {"verbose_name": model._meta.verbose_name}) # Do a post-after-redirect so that reload works, etc. if post_save_redirect: @@ -180,7 +181,7 @@ def delete_object(request, model, post_delete_redirect, if request.method == 'POST': object.delete() if request.user.is_authenticated(): - request.user.message_set.create(message="The %s was deleted." % model._meta.verbose_name) + request.user.message_set.create(message=gettext("The %(verbose_name)s was deleted.") % {"verbose_name": model._meta.verbose_name}) return HttpResponseRedirect(post_delete_redirect) else: if not template_name: |
