summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorJason Pellerin <jpellerin@gmail.com>2006-08-14 01:03:32 +0000
committerJason Pellerin <jpellerin@gmail.com>2006-08-14 01:03:32 +0000
commitbec235deefbca44d1a9f3b95e453d946b1359135 (patch)
treedf09c2bada8a5583800a178a514fe6ba13241bd7 /django
parent238c6ecd5b10c6c76b8b1db03dcb746bcfe366af (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')
-rwxr-xr-xdjango/bin/compile-messages.py2
-rw-r--r--django/conf/global_settings.py1
-rw-r--r--django/conf/project_template/settings.py3
-rw-r--r--django/contrib/admin/templates/admin/change_form.html2
-rw-r--r--django/contrib/admin/templates/admin/edit_inline_tabular.html1
-rw-r--r--django/contrib/admin/urls.py1
-rw-r--r--django/contrib/admin/views/doc.py34
-rw-r--r--django/contrib/admin/views/main.py2
-rw-r--r--django/contrib/flatpages/README.TXT4
-rw-r--r--django/contrib/sessions/middleware.py3
-rw-r--r--django/core/management.py44
-rw-r--r--django/core/servers/basehttp.py4
-rw-r--r--django/core/urlresolvers.py50
-rw-r--r--django/db/backends/ansi/sql.py8
-rw-r--r--django/db/backends/postgresql_psycopg2/base.py4
-rw-r--r--django/db/models/__init__.py4
-rw-r--r--django/db/models/base.py11
-rw-r--r--django/db/models/fields/__init__.py2
-rw-r--r--django/db/models/loading.py4
-rw-r--r--django/db/models/manipulators.py2
-rw-r--r--django/http/__init__.py15
-rw-r--r--django/template/defaultfilters.py4
-rw-r--r--django/template/loaders/filesystem.py2
-rw-r--r--django/views/generic/create_update.py7
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: