From cbe24263692641af8908da21d1a2d333100a468a Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Mon, 31 Oct 2005 03:14:57 +0000 Subject: [PATCH 01/15] Made several grammar fixes to cache documentation from [1020] git-svn-id: http://code.djangoproject.com/svn/django/trunk@1030 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/utils/cache.py | 16 ++++------ docs/cache.txt | 74 +++++++++++++++++++++++++++++-------------- 2 files changed, 57 insertions(+), 33 deletions(-) diff --git a/django/utils/cache.py b/django/utils/cache.py index 631ea8f08d..b36753b558 100644 --- a/django/utils/cache.py +++ b/django/utils/cache.py @@ -22,19 +22,19 @@ from django.conf import settings from django.core.cache import cache cc_delim_re = re.compile(r'\s*,\s*') + def patch_cache_control(response, **kwargs): """ This function patches the Cache-Control header by adding all keyword arguments to it. The transformation is as follows: - - all keyword parameter names are turned to lowercase and - all _ will be translated to - - - if the value of a parameter is True (exatly True, not just a - true value), only the parameter name is added to the header - - all other parameters are added with their value, after applying - str to it. + * All keyword parameter names are turned to lowercase, and underscores + are converted to hyphens. + * If the value of a parameter is True (exactly True, not just a + true value), only the parameter name is added to the header. + * All other parameters are added with their value, after applying + str() to it. """ - def dictitem(s): t = s.split('=',1) if len(t) > 1: @@ -49,9 +49,7 @@ def patch_cache_control(response, **kwargs): return t[0] + '=' + str(t[1]) if response.has_header('Cache-Control'): - print response['Cache-Control'] cc = cc_delim_re.split(response['Cache-Control']) - print cc cc = dict([dictitem(el) for el in cc]) else: cc = {} diff --git a/docs/cache.txt b/docs/cache.txt index c1b1352bca..6c1a3140d5 100644 --- a/docs/cache.txt +++ b/docs/cache.txt @@ -272,39 +272,65 @@ and a list/tuple of header names as its second argument. .. _`HTTP Vary headers`: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44 -Controlling cache: Using Vary headers -===================================== +Controlling cache: Using other headers +====================================== -Another problem with caching is the privacy of data, and the question where data can -be stored in a cascade of caches. A user usually faces two kinds of caches: his own -browser cache (a private cache) and his providers cache (a public cache). A public cache -is used by multiple users and controlled by someone else. This poses problems with private -(in the sense of sensitive) data - you don't want your social security number or your -banking account numbers stored in some public cache. So web applications need a way -to tell the caches what data is private and what is public. +Another problem with caching is the privacy of data and the question of where +data should be stored in a cascade of caches. -Other aspects are the definition how long a page should be cached at max, or wether the -cache should allways check for newer versions and only deliver the cache content when -there were no changes (some caches might deliver cached content even if the server page -changed - just because the cache copy isn't yet expired). +A user usually faces two kinds of caches: his own browser cache (a private +cache) and his provider's cache (a public cache). A public cache is used by +multiple users and controlled by someone else. This poses problems with +sensitive data: You don't want, say, your banking-account number stored in a +public cache. So Web applications need a way to tell caches which data is +private and which is public. -So there are a multitude of options you can control for your pages. This is where the -Cache-Control header (more infos in `HTTP Cache-Control headers`_) comes in. The usage -is quite simple:: +The solution is to indicate a page's cache should be "private." To do this in +Django, use the ``cache_control`` view decorator. Example:: - @cache_control(private=True, must_revalidate=True, max_age=3600) + from django.views.decorators.cache import cache_control + @cache_control(private=True) def my_view(request): ... -This would define the view as private, to be revalidated on every access and cache -copies will only be stored for 3600 seconds at max. +This decorator takes care of sending out the appropriate HTTP header behind the +scenes. -The caching middleware already set's this header up with a max-age of the CACHE_MIDDLEWARE_SETTINGS -setting. And the cache_page decorator does the same. The cache_control decorator correctly merges -different values into one big header, though. But you should take into account that middlewares -might overwrite some of your headers or set their own defaults if you don't give that header yourself. +There are a few other ways to control cache parameters. For example, HTTP +allows applications to do the following: -.. _`HTTP Cache-Control headers`: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 + * Define the maximum time a page should be cached. + * Specify whether a cache should always check for newer versions, only + delivering the cached content when there are no changes. (Some caches + might deliver cached content even if the server page changed -- simply + because the cache copy isn't yet expired.) + +In Django, use the ``cache_control`` view decorator to specify these cache +parameters. In this example, the ``cache_control`` decorator tells caches to +revalidate the cache on every access and to store cached versions for, at most, +3600 seconds:: + + from django.views.decorators.cache import cache_control + @cache_control(must_revalidate=True, max_age=3600) + def my_view(request): + ... + +Any valid Cache-Control directive is valid in ``cache_control()``. For a full +list, see the `Cache-Control spec`_. Just pass the directives as keyword +arguments to ``cache_control()``, substituting underscores for hyphens. For +directives that don't take an argument, set the argument to ``True``. + +Examples: + + ``@cache_control(max_age=3600)`` turns into ``max-age=3600``. + ``@cache_control(public=True)`` turns into ``public``. + +(Note that the caching middleware already sets the cache header's max-age with +the value of the ``CACHE_MIDDLEWARE_SETTINGS`` setting. If you use a custom +``max_age`` in a ``cache_control`` decorator, the decorator will take +precedence, and the header values will be merged correctly.) + +.. _`Cache-Control spec`: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 Other optimizations =================== From 546e368d0b0a0d74b13a756fa67e162709af22e8 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Mon, 31 Oct 2005 03:17:39 +0000 Subject: [PATCH 02/15] More tightening of docs/cache.txt git-svn-id: http://code.djangoproject.com/svn/django/trunk@1031 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/cache.txt | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/cache.txt b/docs/cache.txt index 6c1a3140d5..f8986b9115 100644 --- a/docs/cache.txt +++ b/docs/cache.txt @@ -306,24 +306,23 @@ allows applications to do the following: because the cache copy isn't yet expired.) In Django, use the ``cache_control`` view decorator to specify these cache -parameters. In this example, the ``cache_control`` decorator tells caches to -revalidate the cache on every access and to store cached versions for, at most, -3600 seconds:: +parameters. In this example, ``cache_control`` tells caches to revalidate the +cache on every access and to store cached versions for, at most, 3600 seconds:: from django.views.decorators.cache import cache_control @cache_control(must_revalidate=True, max_age=3600) def my_view(request): ... -Any valid Cache-Control directive is valid in ``cache_control()``. For a full -list, see the `Cache-Control spec`_. Just pass the directives as keyword +Any valid ``Cache-Control`` directive is valid in ``cache_control()``. For a +full list, see the `Cache-Control spec`_. Just pass the directives as keyword arguments to ``cache_control()``, substituting underscores for hyphens. For directives that don't take an argument, set the argument to ``True``. Examples: - ``@cache_control(max_age=3600)`` turns into ``max-age=3600``. - ``@cache_control(public=True)`` turns into ``public``. + * ``@cache_control(max_age=3600)`` turns into ``max-age=3600``. + * ``@cache_control(public=True)`` turns into ``public``. (Note that the caching middleware already sets the cache header's max-age with the value of the ``CACHE_MIDDLEWARE_SETTINGS`` setting. If you use a custom From 3226127aa29c498921f7a7e4209de229d253d21f Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Tue, 1 Nov 2005 00:40:32 +0000 Subject: [PATCH 03/15] Added model unit tests for year, month and day lookup. Refs #659 git-svn-id: http://code.djangoproject.com/svn/django/trunk@1033 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- tests/testapp/models/basic.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/testapp/models/basic.py b/tests/testapp/models/basic.py index ebd784137a..ad2a8cb862 100644 --- a/tests/testapp/models/basic.py +++ b/tests/testapp/models/basic.py @@ -51,6 +51,17 @@ datetime.datetime(2005, 7, 28, 0, 0)
>>> articles.get_object(pub_date__year=2005)
+>>> articles.get_object(pub_date__year=2005, pub_date__month=7) +
+>>> articles.get_object(pub_date__year=2005, pub_date__month=7, pub_date__day=28) +
+ +>>> articles.get_list(pub_date__year=2005) +[
] +>>> articles.get_list(pub_date__year=2004) +[] +>>> articles.get_list(pub_date__year=2005, pub_date__month=7) +[
] # Django raises an ArticleDoesNotExist exception for get_object() >>> articles.get_object(id__exact=2) @@ -58,6 +69,11 @@ Traceback (most recent call last): ... ArticleDoesNotExist: Article does not exist for {'id__exact': 2} +>>> articles.get_object(pub_date__year=2005, pub_date__month=8) +Traceback (most recent call last): + ... +ArticleDoesNotExist: Article does not exist for ... + # Lookup by a primary key is the most common case, so Django provides a # shortcut for primary-key exact lookups. # The following is identical to articles.get_object(id__exact=1). From 41d5cff745c26eab9a0b6ff29d2addfef7c5303a Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Tue, 1 Nov 2005 00:49:52 +0000 Subject: [PATCH 04/15] Fixed #548 -- Added missing step at the end of docs/tutorial04.txt git-svn-id: http://code.djangoproject.com/svn/django/trunk@1034 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/tutorial04.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/tutorial04.txt b/docs/tutorial04.txt index 737d8deb1f..4f9ef3baff 100644 --- a/docs/tutorial04.txt +++ b/docs/tutorial04.txt @@ -213,6 +213,9 @@ The generic views pass ``object`` and ``object_list`` to their templates, so change your templates so that ``latest_poll_list`` becomes ``object_list`` and ``poll`` becomes ``object``. +In the ``vote()`` view, change the template call from ``polls/detail`` to +``polls/polls_detail``, and pass ``object`` in the context instead of ``poll``. + Finally, you can delete the ``index()``, ``detail()`` and ``results()`` views from ``polls/views/polls.py``. We don't need them anymore. From 390666ac2bf8223bede4f78a97836051bc9f9526 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Tue, 1 Nov 2005 01:02:07 +0000 Subject: [PATCH 05/15] Fixed #508 -- Added support for 'expires' in cookies and changed session middleware to set 'expires' in addition to 'max_age'. Thanks, mark@junklight.com git-svn-id: http://code.djangoproject.com/svn/django/trunk@1035 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/middleware/sessions.py | 3 ++- django/utils/httpwrappers.py | 4 ++-- docs/request_response.txt | 4 +++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/django/middleware/sessions.py b/django/middleware/sessions.py index 42b2118410..8b9f21f78d 100644 --- a/django/middleware/sessions.py +++ b/django/middleware/sessions.py @@ -71,6 +71,7 @@ class SessionMiddleware: session_key = request.session.session_key or sessions.get_new_session_key() new_session = sessions.save(session_key, request.session._session, datetime.datetime.now() + datetime.timedelta(seconds=SESSION_COOKIE_AGE)) + expires = datetime.datetime.strftime(datetime.datetime.utcnow() + datetime.timedelta(seconds=SESSION_COOKIE_AGE), "%a, %d-%b-%Y %H:%M:%S GMT") response.set_cookie(SESSION_COOKIE_NAME, session_key, - max_age=SESSION_COOKIE_AGE, domain=SESSION_COOKIE_DOMAIN) + max_age=SESSION_COOKIE_AGE, expires=expires, domain=SESSION_COOKIE_DOMAIN) return response diff --git a/django/utils/httpwrappers.py b/django/utils/httpwrappers.py index 5f9362bd24..c1aa9d6ee1 100644 --- a/django/utils/httpwrappers.py +++ b/django/utils/httpwrappers.py @@ -172,9 +172,9 @@ class HttpResponse: return True return False - def set_cookie(self, key, value='', max_age=None, path='/', domain=None, secure=None): + def set_cookie(self, key, value='', max_age=None, expires=None, path='/', domain=None, secure=None): self.cookies[key] = value - for var in ('max_age', 'path', 'domain', 'secure'): + for var in ('max_age', 'path', 'domain', 'secure', 'expires'): val = locals()[var] if val is not None: self.cookies[key][var.replace('_', '-')] = val diff --git a/docs/request_response.txt b/docs/request_response.txt index 150a5bc92c..85a5e091db 100644 --- a/docs/request_response.txt +++ b/docs/request_response.txt @@ -284,12 +284,14 @@ Methods Returns ``True`` or ``False`` based on a case-insensitive check for a header with the given name. -``set_cookie(key, value='', max_age=None, path='/', domain=None, secure=None)`` +``set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None)`` Sets a cookie. The parameters are the same as in the `cookie Morsel`_ object in the Python standard library. * ``max_age`` should be a number of seconds, or ``None`` (default) if the cookie should last only as long as the client's browser session. + * ``expires`` should be a string in the format + ``"Wdy, DD-Mon-YY HH:MM:SS GMT"``. * Use ``domain`` if you want to set a cross-domain cookie. For example, ``domain=".lawrence.com"`` will set a cookie that is readable by the domains www.lawrence.com, blogs.lawrence.com and From 7136eb8f3a052afef29e343679e84e93d7e9e0a3 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Tue, 1 Nov 2005 01:08:13 +0000 Subject: [PATCH 06/15] Fixed #507 -- Changed MySQL backend so that it uses 'LIKE BINARY' for case-sensitive comparisons -- contains, startswith and endswith. Thanks, Simon git-svn-id: http://code.djangoproject.com/svn/django/trunk@1036 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/core/db/backends/mysql.py | 6 +++--- docs/db-api.txt | 15 +++++++-------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/django/core/db/backends/mysql.py b/django/core/db/backends/mysql.py index 4399b6a6a0..23815a80cb 100644 --- a/django/core/db/backends/mysql.py +++ b/django/core/db/backends/mysql.py @@ -125,15 +125,15 @@ def get_relations(cursor, table_name): OPERATOR_MAPPING = { 'exact': '=', 'iexact': 'LIKE', - 'contains': 'LIKE', + 'contains': 'LIKE BINARY', 'icontains': 'LIKE', 'ne': '!=', 'gt': '>', 'gte': '>=', 'lt': '<', 'lte': '<=', - 'startswith': 'LIKE', - 'endswith': 'LIKE', + 'startswith': 'LIKE BINARY', + 'endswith': 'LIKE BINARY', 'istartswith': 'LIKE', 'iendswith': 'LIKE', } diff --git a/docs/db-api.txt b/docs/db-api.txt index b80d4e8647..1a4f488d50 100644 --- a/docs/db-api.txt +++ b/docs/db-api.txt @@ -161,9 +161,9 @@ The DB API supports the following lookup types: ``foo``, ``FOO``, ``fOo``, etc. contains Case-sensitive containment test: ``polls.get_list(question__contains="spam")`` returns all polls - that contain "spam" in the question. (PostgreSQL only. MySQL - doesn't support case-sensitive LIKE statements; ``contains`` - will act like ``icontains`` for MySQL.) + that contain "spam" in the question. (PostgreSQL and MySQL + only. SQLite doesn't support case-sensitive LIKE statements; + ``contains`` will act like ``icontains`` for SQLite.) icontains Case-insensitive containment test. gt Greater than: ``polls.get_list(id__gt=4)``. gte Greater than or equal to. @@ -174,11 +174,10 @@ The DB API supports the following lookup types: a list of polls whose IDs are either 1, 3 or 4. startswith Case-sensitive starts-with: ``polls.get_list(question_startswith="Would")``. (PostgreSQL - only. MySQL doesn't support case-sensitive LIKE statements; - ``startswith`` will act like ``istartswith`` for MySQL.) - endswith Case-sensitive ends-with. (PostgreSQL only. MySQL doesn't - support case-sensitive LIKE statements; ``endswith`` will act - like ``iendswith`` for MySQL.) + and MySQL only. SQLite doesn't support case-sensitive LIKE + statements; ``startswith`` will act like ``istartswith`` for + SQLite.) + endswith Case-sensitive ends-with. (PostgreSQL and MySQL only.) istartswith Case-insensitive starts-with. iendswith Case-insensitive ends-with. range Range test: From cee6faf43ed92c5b276ca4d2e1754a72fbc00ce1 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Tue, 1 Nov 2005 01:11:36 +0000 Subject: [PATCH 07/15] Fixed #505 -- ssi template tag now displays a message instead of failing silently if DEBUG=True. Thanks, Manuzhai git-svn-id: http://code.djangoproject.com/svn/django/trunk@1037 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/core/template/defaulttags.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/django/core/template/defaulttags.py b/django/core/template/defaulttags.py index ea21ebafce..535d0b81e1 100644 --- a/django/core/template/defaulttags.py +++ b/django/core/template/defaulttags.py @@ -211,8 +211,12 @@ class SsiNode(Node): self.filepath, self.parsed = filepath, parsed def render(self, context): + from django.conf.settings import DEBUG if not include_is_allowed(self.filepath): - return '' # Fail silently for invalid includes. + if DEBUG: + return "[Didn't have permission to include file]" + else: + return '' # Fail silently for invalid includes. try: fp = open(self.filepath, 'r') output = fp.read() @@ -223,8 +227,11 @@ class SsiNode(Node): try: t = Template(output) return t.render(context) - except TemplateSyntaxError: - return '' # Fail silently for invalid included templates. + except (TemplateSyntaxError, e): + if DEBUG: + return "[Included template had syntax error: %s]" % e + else: + return '' # Fail silently for invalid included templates. return output class LoadNode(Node): From c65332d409cf477d4b55f1ff3bacbdea4a0afaff Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Tue, 1 Nov 2005 01:28:42 +0000 Subject: [PATCH 08/15] Updated out-of-date docstring in django/core/db/__init__.py git-svn-id: http://code.djangoproject.com/svn/django/trunk@1038 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/core/db/__init__.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/django/core/db/__init__.py b/django/core/db/__init__.py index c4f06e4c6e..f0ffeebc2e 100644 --- a/django/core/db/__init__.py +++ b/django/core/db/__init__.py @@ -1,16 +1,11 @@ """ This is the core database connection. -All CMS code assumes database SELECT statements cast the resulting values as such: +All Django code assumes database SELECT statements cast the resulting values as such: * booleans are mapped to Python booleans * dates are mapped to Python datetime.date objects * times are mapped to Python datetime.time objects * timestamps are mapped to Python datetime.datetime objects - -Right now, we're handling this by using psycopg's custom typecast definitions. -If we move to a different database module, we should ensure that it either -performs the appropriate typecasting out of the box, or that it has hooks that -let us do that. """ from django.conf.settings import DATABASE_ENGINE From 23bb8c4a4b5e785cd4992689c529f2d9a86898b2 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Tue, 1 Nov 2005 01:32:54 +0000 Subject: [PATCH 09/15] Added quote_name hook for each database backend. Refs #121. Thanks, Robin Munn -- we miss you. git-svn-id: http://code.djangoproject.com/svn/django/trunk@1039 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/core/db/__init__.py | 1 + django/core/db/backends/ado_mssql.py | 4 ++++ django/core/db/backends/mysql.py | 5 +++++ django/core/db/backends/postgresql.py | 5 +++++ django/core/db/backends/sqlite3.py | 5 +++++ 5 files changed, 20 insertions(+) diff --git a/django/core/db/__init__.py b/django/core/db/__init__.py index f0ffeebc2e..6636d4f176 100644 --- a/django/core/db/__init__.py +++ b/django/core/db/__init__.py @@ -36,6 +36,7 @@ get_limit_offset_sql = dbmod.get_limit_offset_sql get_random_function_sql = dbmod.get_random_function_sql get_table_list = dbmod.get_table_list get_relations = dbmod.get_relations +quote_name = dbmod.quote_name OPERATOR_MAPPING = dbmod.OPERATOR_MAPPING DATA_TYPES = dbmod.DATA_TYPES DATA_TYPES_REVERSE = dbmod.DATA_TYPES_REVERSE diff --git a/django/core/db/backends/ado_mssql.py b/django/core/db/backends/ado_mssql.py index 9ea0d5456d..a673c4812e 100644 --- a/django/core/db/backends/ado_mssql.py +++ b/django/core/db/backends/ado_mssql.py @@ -110,6 +110,10 @@ def get_table_list(cursor): def get_relations(cursor, table_name): raise NotImplementedError +def quote_name(name): + # TODO: Figure out how MS-SQL quotes database identifiers. + return name + OPERATOR_MAPPING = { 'exact': '=', 'iexact': 'LIKE', diff --git a/django/core/db/backends/mysql.py b/django/core/db/backends/mysql.py index 23815a80cb..e7ede84a12 100644 --- a/django/core/db/backends/mysql.py +++ b/django/core/db/backends/mysql.py @@ -122,6 +122,11 @@ def get_table_list(cursor): def get_relations(cursor, table_name): raise NotImplementedError +def quote_name(name): + if name.startswith("`") and name.endswith("`"): + return name # Quoting once is enough. + return "`%s`" % name + OPERATOR_MAPPING = { 'exact': '=', 'iexact': 'LIKE', diff --git a/django/core/db/backends/postgresql.py b/django/core/db/backends/postgresql.py index c922fd42f6..a1de11e3df 100644 --- a/django/core/db/backends/postgresql.py +++ b/django/core/db/backends/postgresql.py @@ -116,6 +116,11 @@ def get_relations(cursor, table_name): continue return relations +def quote_name(name): + if name.startswith('"') and name.endswith('"'): + return name # Quoting once is enough. + return '"%s"' % name + # Register these custom typecasts, because Django expects dates/times to be # in Python's native (standard-library) datetime/time format, whereas psycopg # use mx.DateTime by default. diff --git a/django/core/db/backends/sqlite3.py b/django/core/db/backends/sqlite3.py index ea05302a61..3fde8c77e1 100644 --- a/django/core/db/backends/sqlite3.py +++ b/django/core/db/backends/sqlite3.py @@ -124,6 +124,11 @@ def get_table_list(cursor): def get_relations(cursor, table_name): raise NotImplementedError +def quote_name(name): + if name.startswith('"') and name.endswith('"'): + return name # Quoting once is enough. + return '"%s"' % name + # Operators and fields ######################################################## OPERATOR_MAPPING = { From 27efe14c54f3711fcb21cd2d5187be21c94b9117 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Wed, 2 Nov 2005 14:26:55 +0000 Subject: [PATCH 10/15] Added 'Session IDs in URLs' and 'Session cookies' sections to docs/sessions.txt git-svn-id: http://code.djangoproject.com/svn/django/trunk@1044 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/sessions.txt | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/docs/sessions.txt b/docs/sessions.txt index b18ca25a2c..8aa711ea23 100644 --- a/docs/sessions.txt +++ b/docs/sessions.txt @@ -158,6 +158,39 @@ This is necessary because the dictionary is stored in an encoded format:: >>> s.get_decoded() {'user_id': 42} +Session cookies +=============== + +A few `Django settings`_ give you control over the session cookie: + +SESSION_COOKIE_AGE +------------------ + +Default: ``1209600`` (2 weeks, in seconds) + +The age of session cookies, in seconds. + +SESSION_COOKIE_DOMAIN +--------------------- + +Default: ``None`` + +The domain to use for session cookies. Set this to a string such as +``".lawrence.com"`` for cross-domain cookies, or use ``None`` for a standard +domain cookie. + +SESSION_COOKIE_NAME +------------------- + +Default: ``'hotclub'`` + +The name of the cookie to use for sessions. This can be whatever you want. + +``'hotclub'`` is a reference to the Hot Club of France, the band Django +Reinhardt played in. + +.. _Django settings: http://www.djangoproject.com/documentation/settings/ + Technical details ================= @@ -170,3 +203,12 @@ Technical details data, it won't send a session cookie. .. _`the pickle module`: http://www.python.org/doc/current/lib/module-pickle.html + +Session IDs in URLs +=================== + +The Django sessions framework is entirely, and solely, cookie-based. It does +not fall back to putting session IDs in URLs as a last resort, as PHP does. +This is an intentional design decision. Not only does that behavior make URLs +ugly, it makes your site vulnerable to session-ID theft via the "Referer" +header. From 91a283583cf17b9241bd1b9882783a8aedba4d8e Mon Sep 17 00:00:00 2001 From: Jacob Kaplan-Moss Date: Wed, 2 Nov 2005 19:01:27 +0000 Subject: [PATCH 11/15] Made floatformat filter not choke on non-floats git-svn-id: http://code.djangoproject.com/svn/django/trunk@1050 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/core/template/defaultfilters.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/django/core/template/defaultfilters.py b/django/core/template/defaultfilters.py index 2604caf7f9..3a25add5e1 100644 --- a/django/core/template/defaultfilters.py +++ b/django/core/template/defaultfilters.py @@ -27,7 +27,10 @@ def floatformat(text, _): Displays a floating point number as 34.2 (with one decimal place) -- but only if there's a point to be displayed """ - f = float(text) + try: + f = float(text) + except ValueError: + return '' m = f - int(f) if m: return '%.1f' % f From b5df9c308f169cdeaa9bf4490ed925cf95d0243a Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Wed, 2 Nov 2005 20:31:12 +0000 Subject: [PATCH 12/15] Improved docs/db-api.txt to specify that case-sensitive ordering isn't supported git-svn-id: http://code.djangoproject.com/svn/django/trunk@1051 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/db-api.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/db-api.txt b/docs/db-api.txt index 1a4f488d50..01aacf49b1 100644 --- a/docs/db-api.txt +++ b/docs/db-api.txt @@ -239,6 +239,10 @@ so:: polls.get_list(order_by=['?']) +There's no way to specify whether ordering should be case sensitive. With +respect to case-sensitivity, Django will order results however your database +backend normally orders them. + Relationships (joins) ===================== From 2d5c6ec2566ad13d4b2a6cd596b6c6c4dac74151 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Wed, 2 Nov 2005 21:53:32 +0000 Subject: [PATCH 13/15] Changed docs/legacy_databases.txt to link to settings docs git-svn-id: http://code.djangoproject.com/svn/django/trunk@1052 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/legacy_databases.txt | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/docs/legacy_databases.txt b/docs/legacy_databases.txt index e08580504c..9ffe6c5efc 100644 --- a/docs/legacy_databases.txt +++ b/docs/legacy_databases.txt @@ -16,17 +16,20 @@ Give Django your database parameters You'll need to tell Django what your database connection parameters are, and what the name of the database is. Do that by editing these settings in your -settings file: +`settings file`_: - * ``DATABASE_ENGINE`` - * ``DATABASE_USER`` - * ``DATABASE_PASSWORD`` - * ``DATABASE_NAME`` - * ``DATABASE_HOST`` + * `DATABASE_ENGINE`_ + * `DATABASE_USER`_ + * `DATABASE_PASSWORD`_ + * `DATABASE_NAME`_ + * `DATABASE_HOST`_ -For more information on these settings see `Tutorial 1`_. - -.. _Tutorial 1: http://www.djangoproject.com/documentation/tutorial1/ +.. _settings file: http://www.djangoproject.com/documentation/settings/ +.. _DATABASE_ENGINE: http://www.djangoproject.com/documentation/settings/#database-engine +.. _DATABASE_USER: http://www.djangoproject.com/documentation/settings/#database-user +.. _DATABASE_PASSWORD: http://www.djangoproject.com/documentation/settings/#database-password +.. _DATABASE_NAME: http://www.djangoproject.com/documentation/settings/#database-name +.. _DATABASE_HOST: http://www.djangoproject.com/documentation/settings/#database-host Auto-generate the models ======================== From f29205fc7be8ad1777f3d73f6061a460e8bc07cb Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Wed, 2 Nov 2005 21:55:21 +0000 Subject: [PATCH 14/15] Updated docs/legacy_databases.txt to remove 'auth_admin_log' from list of tables that shouldn't be in the database, because that's now optional. git-svn-id: http://code.djangoproject.com/svn/django/trunk@1053 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/legacy_databases.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/legacy_databases.txt b/docs/legacy_databases.txt index 9ffe6c5efc..96df5a375d 100644 --- a/docs/legacy_databases.txt +++ b/docs/legacy_databases.txt @@ -75,7 +75,6 @@ following names: * ``auth_groups`` * ``auth_users`` * ``auth_messages`` - * ``auth_admin_log`` * ``auth_groups_permissions`` * ``auth_users_groups`` * ``auth_users_user_permissions`` From cb45fd0ae20597306cd1f877efc99d9bd7cbee98 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Wed, 2 Nov 2005 22:28:08 +0000 Subject: [PATCH 15/15] Added DATABASE_PORT to docs/legacy_databases.txt git-svn-id: http://code.djangoproject.com/svn/django/trunk@1054 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/legacy_databases.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/legacy_databases.txt b/docs/legacy_databases.txt index 96df5a375d..beddc74134 100644 --- a/docs/legacy_databases.txt +++ b/docs/legacy_databases.txt @@ -23,6 +23,7 @@ what the name of the database is. Do that by editing these settings in your * `DATABASE_PASSWORD`_ * `DATABASE_NAME`_ * `DATABASE_HOST`_ + * `DATABASE_PORT`_ .. _settings file: http://www.djangoproject.com/documentation/settings/ .. _DATABASE_ENGINE: http://www.djangoproject.com/documentation/settings/#database-engine @@ -30,6 +31,7 @@ what the name of the database is. Do that by editing these settings in your .. _DATABASE_PASSWORD: http://www.djangoproject.com/documentation/settings/#database-password .. _DATABASE_NAME: http://www.djangoproject.com/documentation/settings/#database-name .. _DATABASE_HOST: http://www.djangoproject.com/documentation/settings/#database-host +.. _DATABASE_PORT: http://www.djangoproject.com/documentation/settings/#database-port Auto-generate the models ========================