diff options
| author | Christopher Long <indirecthit@gmail.com> | 2006-08-20 22:49:48 +0000 |
|---|---|---|
| committer | Christopher Long <indirecthit@gmail.com> | 2006-08-20 22:49:48 +0000 |
| commit | 49c1c2fdd3a4b997aa009faf85a9ae6665fa4e00 (patch) | |
| tree | 481132d05d747ddbb998bdce57fc516fbc88438d /django | |
| parent | 455842e07e44c63f45850e7471b1f19826af6235 (diff) | |
[per-object-permissions] Update to trunk
git-svn-id: http://code.djangoproject.com/svn/django/branches/per-object-permissions@3630 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django')
| -rwxr-xr-x | django/bin/compile-messages.py | 11 | ||||
| -rw-r--r-- | django/conf/project_template/settings.py | 4 | ||||
| -rw-r--r-- | django/contrib/admin/templates/admin/base.html | 1 | ||||
| -rw-r--r-- | django/contrib/admin/views/doc.py | 2 | ||||
| -rw-r--r-- | django/contrib/admin/views/main.py | 16 | ||||
| -rw-r--r-- | django/core/cache/backends/memcached.py | 2 | ||||
| -rw-r--r-- | django/middleware/cache.py | 3 | ||||
| -rw-r--r-- | django/middleware/http.py | 24 |
8 files changed, 57 insertions, 6 deletions
diff --git a/django/bin/compile-messages.py b/django/bin/compile-messages.py index 44a84de379..07dcce7bf6 100755 --- a/django/bin/compile-messages.py +++ b/django/bin/compile-messages.py @@ -11,7 +11,7 @@ def compile_messages(): elif os.path.isdir('locale'): basedir = os.path.abspath('locale') else: - print "this script should be run from the django svn tree or your project or app tree" + 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): @@ -19,7 +19,14 @@ def compile_messages(): if f.endswith('.po'): sys.stderr.write('processing file %s in %s\n' % (f, dirpath)) pf = os.path.splitext(os.path.join(dirpath, f))[0] - cmd = 'msgfmt -o "%s.mo" "%s.po"' % (pf, pf) + # Store the names of the .mo and .po files in an environment + # variable, rather than doing a string replacement into the + # command, so that we can take advantage of shell quoting, to + # quote any malicious characters/escaping. + # See http://cyberelk.net/tim/articles/cmdline/ar01s02.html + os.environ['djangocompilemo'] = pf + '.mo' + os.environ['djangocompilepo'] = pf + '.po' + cmd = 'msgfmt -o "$djangocompilemo" "$djangocompilepo"' os.system(cmd) if __name__ == "__main__": diff --git a/django/conf/project_template/settings.py b/django/conf/project_template/settings.py index 63e07c061a..d6f34a28db 100644 --- a/django/conf/project_template/settings.py +++ b/django/conf/project_template/settings.py @@ -27,6 +27,10 @@ LANGUAGE_CODE = 'en-us' SITE_ID = 1 +# If you set this to False, Django will make some optimizations so as not +# to load the internationalization machinery. +USE_I18N = True + # Absolute path to the directory that holds media. # Example: "/home/media/media.lawrence.com/" MEDIA_ROOT = '' diff --git a/django/contrib/admin/templates/admin/base.html b/django/contrib/admin/templates/admin/base.html index 41514e6a81..b63604b268 100644 --- a/django/contrib/admin/templates/admin/base.html +++ b/django/contrib/admin/templates/admin/base.html @@ -6,6 +6,7 @@ {% if LANGUAGE_BIDI %}<link rel="stylesheet" type="text/css" href="{% block stylesheet_rtl %}{% admin_media_prefix %}css/rtl.css{% endblock %}" />{% endif %} {% block extrastyle %}{% endblock %} {% block extrahead %}{% endblock %} +{% block blockbots %}<meta name="robots" content="NONE,NOARCHIVE" />{% endblock %} </head> {% load i18n %} diff --git a/django/contrib/admin/views/doc.py b/django/contrib/admin/views/doc.py index d1541abee9..b724cc5485 100644 --- a/django/contrib/admin/views/doc.py +++ b/django/contrib/admin/views/doc.py @@ -226,7 +226,7 @@ def model_detail(request, app_label, model_name): return render_to_response('admin_doc/model_detail.html', { 'name': '%s.%s' % (opts.app_label, opts.object_name), - 'summary': "Fields on %s objects" % opts.object_name, + 'summary': _("Fields on %s objects") % opts.object_name, 'description': model.__doc__, 'fields': fields, }, context_instance=RequestContext(request)) diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 25f7eeaa70..2a8b135bc7 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -272,7 +272,9 @@ 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, %r, "%s");</script>' % \ + if type(pk_value) is str: # Quote if string, so JavaScript doesn't think it's a variable. + pk_value = '"%s"' % pk_value.replace('"', '\\"') + return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %s, "%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)) @@ -734,9 +736,19 @@ class ChangeList(object): qs = qs.order_by((self.order_type == 'desc' and '-' or '') + lookup_order_field) # Apply keyword searches. + def construct_search(field_name): + if field_name.startswith('^'): + return "%s__istartswith" % field_name[1:] + elif field_name.startswith('='): + return "%s__iexact" % field_name[1:] + elif field_name.startswith('@'): + return "%s__search" % field_name[1:] + else: + return "%s__icontains" % field_name + if self.lookup_opts.admin.search_fields and self.query: for bit in self.query.split(): - or_queries = [models.Q(**{'%s__icontains' % field_name: bit}) for field_name in self.lookup_opts.admin.search_fields] + or_queries = [models.Q(**{construct_search(field_name): bit}) for field_name in self.lookup_opts.admin.search_fields] other_qs = QuerySet(self.model) other_qs = other_qs.filter(reduce(operator.or_, or_queries)) qs = qs & other_qs diff --git a/django/core/cache/backends/memcached.py b/django/core/cache/backends/memcached.py index 86ae096d2c..180f95da73 100644 --- a/django/core/cache/backends/memcached.py +++ b/django/core/cache/backends/memcached.py @@ -20,7 +20,7 @@ class CacheClass(BaseCache): return val def set(self, key, value, timeout=0): - self._cache.set(key, value, timeout) + self._cache.set(key, value, timeout or self.default_timeout) def delete(self, key): self._cache.delete(key) diff --git a/django/middleware/cache.py b/django/middleware/cache.py index 08e77d1375..58800b24da 100644 --- a/django/middleware/cache.py +++ b/django/middleware/cache.py @@ -41,6 +41,9 @@ class CacheMiddleware(object): def process_request(self, request): "Checks whether the page is already cached and returns the cached version if available." + if self.cache_anonymous_only: + assert hasattr(request, 'user'), "The Django cache middleware with CACHE_MIDDLEWARE_ANONYMOUS_ONLY=True requires authentication middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.auth.middleware.AuthenticationMiddleware' before the CacheMiddleware." + if not request.method in ('GET', 'HEAD') or request.GET: request._cache_update_cache = False return None # Don't bother checking the cache. diff --git a/django/middleware/http.py b/django/middleware/http.py index 12d0c0f683..3ebd8ffd1a 100644 --- a/django/middleware/http.py +++ b/django/middleware/http.py @@ -35,3 +35,27 @@ class ConditionalGetMiddleware(object): response.content = '' return response + +class SetRemoteAddrFromForwardedFor(object): + """ + Middleware that sets REMOTE_ADDR based on HTTP_X_FORWARDED_FOR, if the + latter is set. This is useful if you're sitting behind a reverse proxy that + causes each request's REMOTE_ADDR to be set to 127.0.0.1. + + Note that this does NOT validate HTTP_X_FORWARDED_FOR. If you're not behind + a reverse proxy that sets HTTP_X_FORWARDED_FOR automatically, do not use + this middleware. Anybody can spoof the value of HTTP_X_FORWARDED_FOR, and + because this sets REMOTE_ADDR based on HTTP_X_FORWARDED_FOR, that means + anybody can "fake" their IP address. Only use this when you can absolutely + trust the value of HTTP_X_FORWARDED_FOR. + """ + def process_request(self, request): + try: + real_ip = request.META['HTTP_X_FORWARDED_FOR'] + except KeyError: + return None + else: + # HTTP_X_FORWARDED_FOR can be a comma-separated list of IPs. + # Take just the first one. + real_ip = real_ip.split(",")[0] + request.META['REMOTE_ADDR'] = real_ip |
