mirror of
https://github.com/django/django.git
synced 2025-07-04 01:39:20 +00:00
i18n: merged to [1054] of trunk
git-svn-id: http://code.djangoproject.com/svn/django/branches/i18n@1067 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
commit
e27211a0de
@ -1,16 +1,11 @@
|
|||||||
"""
|
"""
|
||||||
This is the core database connection.
|
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
|
* booleans are mapped to Python booleans
|
||||||
* dates are mapped to Python datetime.date objects
|
* dates are mapped to Python datetime.date objects
|
||||||
* times are mapped to Python datetime.time objects
|
* times are mapped to Python datetime.time objects
|
||||||
* timestamps are mapped to Python datetime.datetime 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 django.conf.settings import DATABASE_ENGINE
|
||||||
@ -41,6 +36,7 @@ get_limit_offset_sql = dbmod.get_limit_offset_sql
|
|||||||
get_random_function_sql = dbmod.get_random_function_sql
|
get_random_function_sql = dbmod.get_random_function_sql
|
||||||
get_table_list = dbmod.get_table_list
|
get_table_list = dbmod.get_table_list
|
||||||
get_relations = dbmod.get_relations
|
get_relations = dbmod.get_relations
|
||||||
|
quote_name = dbmod.quote_name
|
||||||
OPERATOR_MAPPING = dbmod.OPERATOR_MAPPING
|
OPERATOR_MAPPING = dbmod.OPERATOR_MAPPING
|
||||||
DATA_TYPES = dbmod.DATA_TYPES
|
DATA_TYPES = dbmod.DATA_TYPES
|
||||||
DATA_TYPES_REVERSE = dbmod.DATA_TYPES_REVERSE
|
DATA_TYPES_REVERSE = dbmod.DATA_TYPES_REVERSE
|
||||||
|
@ -110,6 +110,10 @@ def get_table_list(cursor):
|
|||||||
def get_relations(cursor, table_name):
|
def get_relations(cursor, table_name):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def quote_name(name):
|
||||||
|
# TODO: Figure out how MS-SQL quotes database identifiers.
|
||||||
|
return name
|
||||||
|
|
||||||
OPERATOR_MAPPING = {
|
OPERATOR_MAPPING = {
|
||||||
'exact': '=',
|
'exact': '=',
|
||||||
'iexact': 'LIKE',
|
'iexact': 'LIKE',
|
||||||
|
@ -122,18 +122,23 @@ def get_table_list(cursor):
|
|||||||
def get_relations(cursor, table_name):
|
def get_relations(cursor, table_name):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def quote_name(name):
|
||||||
|
if name.startswith("`") and name.endswith("`"):
|
||||||
|
return name # Quoting once is enough.
|
||||||
|
return "`%s`" % name
|
||||||
|
|
||||||
OPERATOR_MAPPING = {
|
OPERATOR_MAPPING = {
|
||||||
'exact': '=',
|
'exact': '=',
|
||||||
'iexact': 'LIKE',
|
'iexact': 'LIKE',
|
||||||
'contains': 'LIKE',
|
'contains': 'LIKE BINARY',
|
||||||
'icontains': 'LIKE',
|
'icontains': 'LIKE',
|
||||||
'ne': '!=',
|
'ne': '!=',
|
||||||
'gt': '>',
|
'gt': '>',
|
||||||
'gte': '>=',
|
'gte': '>=',
|
||||||
'lt': '<',
|
'lt': '<',
|
||||||
'lte': '<=',
|
'lte': '<=',
|
||||||
'startswith': 'LIKE',
|
'startswith': 'LIKE BINARY',
|
||||||
'endswith': 'LIKE',
|
'endswith': 'LIKE BINARY',
|
||||||
'istartswith': 'LIKE',
|
'istartswith': 'LIKE',
|
||||||
'iendswith': 'LIKE',
|
'iendswith': 'LIKE',
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,11 @@ def get_relations(cursor, table_name):
|
|||||||
continue
|
continue
|
||||||
return relations
|
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
|
# Register these custom typecasts, because Django expects dates/times to be
|
||||||
# in Python's native (standard-library) datetime/time format, whereas psycopg
|
# in Python's native (standard-library) datetime/time format, whereas psycopg
|
||||||
# use mx.DateTime by default.
|
# use mx.DateTime by default.
|
||||||
|
@ -124,6 +124,11 @@ def get_table_list(cursor):
|
|||||||
def get_relations(cursor, table_name):
|
def get_relations(cursor, table_name):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def quote_name(name):
|
||||||
|
if name.startswith('"') and name.endswith('"'):
|
||||||
|
return name # Quoting once is enough.
|
||||||
|
return '"%s"' % name
|
||||||
|
|
||||||
# Operators and fields ########################################################
|
# Operators and fields ########################################################
|
||||||
|
|
||||||
OPERATOR_MAPPING = {
|
OPERATOR_MAPPING = {
|
||||||
|
@ -27,7 +27,10 @@ def floatformat(text, _):
|
|||||||
Displays a floating point number as 34.2 (with one decimal place) -- but
|
Displays a floating point number as 34.2 (with one decimal place) -- but
|
||||||
only if there's a point to be displayed
|
only if there's a point to be displayed
|
||||||
"""
|
"""
|
||||||
f = float(text)
|
try:
|
||||||
|
f = float(text)
|
||||||
|
except ValueError:
|
||||||
|
return ''
|
||||||
m = f - int(f)
|
m = f - int(f)
|
||||||
if m:
|
if m:
|
||||||
return '%.1f' % f
|
return '%.1f' % f
|
||||||
|
@ -214,8 +214,12 @@ class SsiNode(Node):
|
|||||||
self.filepath, self.parsed = filepath, parsed
|
self.filepath, self.parsed = filepath, parsed
|
||||||
|
|
||||||
def render(self, context):
|
def render(self, context):
|
||||||
|
from django.conf.settings import DEBUG
|
||||||
if not include_is_allowed(self.filepath):
|
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:
|
try:
|
||||||
fp = open(self.filepath, 'r')
|
fp = open(self.filepath, 'r')
|
||||||
output = fp.read()
|
output = fp.read()
|
||||||
@ -226,8 +230,11 @@ class SsiNode(Node):
|
|||||||
try:
|
try:
|
||||||
t = Template(output)
|
t = Template(output)
|
||||||
return t.render(context)
|
return t.render(context)
|
||||||
except TemplateSyntaxError:
|
except (TemplateSyntaxError, e):
|
||||||
return '' # Fail silently for invalid included templates.
|
if DEBUG:
|
||||||
|
return "[Included template had syntax error: %s]" % e
|
||||||
|
else:
|
||||||
|
return '' # Fail silently for invalid included templates.
|
||||||
return output
|
return output
|
||||||
|
|
||||||
class LoadNode(Node):
|
class LoadNode(Node):
|
||||||
|
@ -71,6 +71,7 @@ class SessionMiddleware:
|
|||||||
session_key = request.session.session_key or sessions.get_new_session_key()
|
session_key = request.session.session_key or sessions.get_new_session_key()
|
||||||
new_session = sessions.save(session_key, request.session._session,
|
new_session = sessions.save(session_key, request.session._session,
|
||||||
datetime.datetime.now() + datetime.timedelta(seconds=SESSION_COOKIE_AGE))
|
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,
|
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
|
return response
|
||||||
|
@ -22,19 +22,19 @@ from django.conf import settings
|
|||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
|
|
||||||
cc_delim_re = re.compile(r'\s*,\s*')
|
cc_delim_re = re.compile(r'\s*,\s*')
|
||||||
|
|
||||||
def patch_cache_control(response, **kwargs):
|
def patch_cache_control(response, **kwargs):
|
||||||
"""
|
"""
|
||||||
This function patches the Cache-Control header by adding all
|
This function patches the Cache-Control header by adding all
|
||||||
keyword arguments to it. The transformation is as follows:
|
keyword arguments to it. The transformation is as follows:
|
||||||
|
|
||||||
- all keyword parameter names are turned to lowercase and
|
* All keyword parameter names are turned to lowercase, and underscores
|
||||||
all _ will be translated to -
|
are converted to hyphens.
|
||||||
- if the value of a parameter is True (exatly True, not just a
|
* If the value of a parameter is True (exactly True, not just a
|
||||||
true value), only the parameter name is added to the header
|
true value), only the parameter name is added to the header.
|
||||||
- all other parameters are added with their value, after applying
|
* All other parameters are added with their value, after applying
|
||||||
str to it.
|
str() to it.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def dictitem(s):
|
def dictitem(s):
|
||||||
t = s.split('=',1)
|
t = s.split('=',1)
|
||||||
if len(t) > 1:
|
if len(t) > 1:
|
||||||
|
@ -172,9 +172,9 @@ class HttpResponse:
|
|||||||
return True
|
return True
|
||||||
return False
|
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
|
self.cookies[key] = value
|
||||||
for var in ('max_age', 'path', 'domain', 'secure'):
|
for var in ('max_age', 'path', 'domain', 'secure', 'expires'):
|
||||||
val = locals()[var]
|
val = locals()[var]
|
||||||
if val is not None:
|
if val is not None:
|
||||||
self.cookies[key][var.replace('_', '-')] = val
|
self.cookies[key][var.replace('_', '-')] = val
|
||||||
|
@ -272,39 +272,64 @@ 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
|
.. _`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
|
Another problem with caching is the privacy of data and the question of where
|
||||||
be stored in a cascade of caches. A user usually faces two kinds of caches: his own
|
data should be stored in a cascade of caches.
|
||||||
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.
|
|
||||||
|
|
||||||
Other aspects are the definition how long a page should be cached at max, or wether the
|
A user usually faces two kinds of caches: his own browser cache (a private
|
||||||
cache should allways check for newer versions and only deliver the cache content when
|
cache) and his provider's cache (a public cache). A public cache is used by
|
||||||
there were no changes (some caches might deliver cached content even if the server page
|
multiple users and controlled by someone else. This poses problems with
|
||||||
changed - just because the cache copy isn't yet expired).
|
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
|
The solution is to indicate a page's cache should be "private." To do this in
|
||||||
Cache-Control header (more infos in `HTTP Cache-Control headers`_) comes in. The usage
|
Django, use the ``cache_control`` view decorator. Example::
|
||||||
is quite simple::
|
|
||||||
|
|
||||||
@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):
|
def my_view(request):
|
||||||
...
|
...
|
||||||
|
|
||||||
This would define the view as private, to be revalidated on every access and cache
|
This decorator takes care of sending out the appropriate HTTP header behind the
|
||||||
copies will only be stored for 3600 seconds at max.
|
scenes.
|
||||||
|
|
||||||
The caching middleware already set's this header up with a max-age of the CACHE_MIDDLEWARE_SETTINGS
|
There are a few other ways to control cache parameters. For example, HTTP
|
||||||
setting. And the cache_page decorator does the same. The cache_control decorator correctly merges
|
allows applications to do the following:
|
||||||
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.
|
|
||||||
|
|
||||||
.. _`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, ``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
|
||||||
|
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
|
Other optimizations
|
||||||
===================
|
===================
|
||||||
|
@ -161,9 +161,9 @@ The DB API supports the following lookup types:
|
|||||||
``foo``, ``FOO``, ``fOo``, etc.
|
``foo``, ``FOO``, ``fOo``, etc.
|
||||||
contains Case-sensitive containment test:
|
contains Case-sensitive containment test:
|
||||||
``polls.get_list(question__contains="spam")`` returns all polls
|
``polls.get_list(question__contains="spam")`` returns all polls
|
||||||
that contain "spam" in the question. (PostgreSQL only. MySQL
|
that contain "spam" in the question. (PostgreSQL and MySQL
|
||||||
doesn't support case-sensitive LIKE statements; ``contains``
|
only. SQLite doesn't support case-sensitive LIKE statements;
|
||||||
will act like ``icontains`` for MySQL.)
|
``contains`` will act like ``icontains`` for SQLite.)
|
||||||
icontains Case-insensitive containment test.
|
icontains Case-insensitive containment test.
|
||||||
gt Greater than: ``polls.get_list(id__gt=4)``.
|
gt Greater than: ``polls.get_list(id__gt=4)``.
|
||||||
gte Greater than or equal to.
|
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.
|
a list of polls whose IDs are either 1, 3 or 4.
|
||||||
startswith Case-sensitive starts-with:
|
startswith Case-sensitive starts-with:
|
||||||
``polls.get_list(question_startswith="Would")``. (PostgreSQL
|
``polls.get_list(question_startswith="Would")``. (PostgreSQL
|
||||||
only. MySQL doesn't support case-sensitive LIKE statements;
|
and MySQL only. SQLite doesn't support case-sensitive LIKE
|
||||||
``startswith`` will act like ``istartswith`` for MySQL.)
|
statements; ``startswith`` will act like ``istartswith`` for
|
||||||
endswith Case-sensitive ends-with. (PostgreSQL only. MySQL doesn't
|
SQLite.)
|
||||||
support case-sensitive LIKE statements; ``endswith`` will act
|
endswith Case-sensitive ends-with. (PostgreSQL and MySQL only.)
|
||||||
like ``iendswith`` for MySQL.)
|
|
||||||
istartswith Case-insensitive starts-with.
|
istartswith Case-insensitive starts-with.
|
||||||
iendswith Case-insensitive ends-with.
|
iendswith Case-insensitive ends-with.
|
||||||
range Range test:
|
range Range test:
|
||||||
@ -240,6 +239,10 @@ so::
|
|||||||
|
|
||||||
polls.get_list(order_by=['?'])
|
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)
|
Relationships (joins)
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
|
@ -16,17 +16,22 @@ Give Django your database parameters
|
|||||||
|
|
||||||
You'll need to tell Django what your database connection parameters are, and
|
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
|
what the name of the database is. Do that by editing these settings in your
|
||||||
settings file:
|
`settings file`_:
|
||||||
|
|
||||||
* ``DATABASE_ENGINE``
|
* `DATABASE_ENGINE`_
|
||||||
* ``DATABASE_USER``
|
* `DATABASE_USER`_
|
||||||
* ``DATABASE_PASSWORD``
|
* `DATABASE_PASSWORD`_
|
||||||
* ``DATABASE_NAME``
|
* `DATABASE_NAME`_
|
||||||
* ``DATABASE_HOST``
|
* `DATABASE_HOST`_
|
||||||
|
* `DATABASE_PORT`_
|
||||||
|
|
||||||
For more information on these settings see `Tutorial 1`_.
|
.. _settings file: http://www.djangoproject.com/documentation/settings/
|
||||||
|
.. _DATABASE_ENGINE: http://www.djangoproject.com/documentation/settings/#database-engine
|
||||||
.. _Tutorial 1: http://www.djangoproject.com/documentation/tutorial1/
|
.. _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
|
||||||
|
.. _DATABASE_PORT: http://www.djangoproject.com/documentation/settings/#database-port
|
||||||
|
|
||||||
Auto-generate the models
|
Auto-generate the models
|
||||||
========================
|
========================
|
||||||
@ -72,7 +77,6 @@ following names:
|
|||||||
* ``auth_groups``
|
* ``auth_groups``
|
||||||
* ``auth_users``
|
* ``auth_users``
|
||||||
* ``auth_messages``
|
* ``auth_messages``
|
||||||
* ``auth_admin_log``
|
|
||||||
* ``auth_groups_permissions``
|
* ``auth_groups_permissions``
|
||||||
* ``auth_users_groups``
|
* ``auth_users_groups``
|
||||||
* ``auth_users_user_permissions``
|
* ``auth_users_user_permissions``
|
||||||
|
@ -284,12 +284,14 @@ Methods
|
|||||||
Returns ``True`` or ``False`` based on a case-insensitive check for a
|
Returns ``True`` or ``False`` based on a case-insensitive check for a
|
||||||
header with the given name.
|
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`_
|
Sets a cookie. The parameters are the same as in the `cookie Morsel`_
|
||||||
object in the Python standard library.
|
object in the Python standard library.
|
||||||
|
|
||||||
* ``max_age`` should be a number of seconds, or ``None`` (default) if
|
* ``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.
|
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,
|
* Use ``domain`` if you want to set a cross-domain cookie. For example,
|
||||||
``domain=".lawrence.com"`` will set a cookie that is readable by
|
``domain=".lawrence.com"`` will set a cookie that is readable by
|
||||||
the domains www.lawrence.com, blogs.lawrence.com and
|
the domains www.lawrence.com, blogs.lawrence.com and
|
||||||
|
@ -158,6 +158,39 @@ This is necessary because the dictionary is stored in an encoded format::
|
|||||||
>>> s.get_decoded()
|
>>> s.get_decoded()
|
||||||
{'user_id': 42}
|
{'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
|
Technical details
|
||||||
=================
|
=================
|
||||||
|
|
||||||
@ -170,3 +203,12 @@ Technical details
|
|||||||
data, it won't send a session cookie.
|
data, it won't send a session cookie.
|
||||||
|
|
||||||
.. _`the pickle module`: http://www.python.org/doc/current/lib/module-pickle.html
|
.. _`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.
|
||||||
|
@ -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
|
change your templates so that ``latest_poll_list`` becomes ``object_list`` and
|
||||||
``poll`` becomes ``object``.
|
``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
|
Finally, you can delete the ``index()``, ``detail()`` and ``results()`` views
|
||||||
from ``polls/views/polls.py``. We don't need them anymore.
|
from ``polls/views/polls.py``. We don't need them anymore.
|
||||||
|
|
||||||
|
@ -51,6 +51,17 @@ datetime.datetime(2005, 7, 28, 0, 0)
|
|||||||
<Article object>
|
<Article object>
|
||||||
>>> articles.get_object(pub_date__year=2005)
|
>>> articles.get_object(pub_date__year=2005)
|
||||||
<Article object>
|
<Article object>
|
||||||
|
>>> articles.get_object(pub_date__year=2005, pub_date__month=7)
|
||||||
|
<Article object>
|
||||||
|
>>> articles.get_object(pub_date__year=2005, pub_date__month=7, pub_date__day=28)
|
||||||
|
<Article object>
|
||||||
|
|
||||||
|
>>> articles.get_list(pub_date__year=2005)
|
||||||
|
[<Article object>]
|
||||||
|
>>> articles.get_list(pub_date__year=2004)
|
||||||
|
[]
|
||||||
|
>>> articles.get_list(pub_date__year=2005, pub_date__month=7)
|
||||||
|
[<Article object>]
|
||||||
|
|
||||||
# Django raises an ArticleDoesNotExist exception for get_object()
|
# Django raises an ArticleDoesNotExist exception for get_object()
|
||||||
>>> articles.get_object(id__exact=2)
|
>>> articles.get_object(id__exact=2)
|
||||||
@ -58,6 +69,11 @@ Traceback (most recent call last):
|
|||||||
...
|
...
|
||||||
ArticleDoesNotExist: Article does not exist for {'id__exact': 2}
|
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
|
# Lookup by a primary key is the most common case, so Django provides a
|
||||||
# shortcut for primary-key exact lookups.
|
# shortcut for primary-key exact lookups.
|
||||||
# The following is identical to articles.get_object(id__exact=1).
|
# The following is identical to articles.get_object(id__exact=1).
|
||||||
|
Loading…
x
Reference in New Issue
Block a user