Changeset 1067
- Timestamp:
- 11/03/05 15:29:48 (3 years ago)
- Files:
-
- django/branches/i18n/django/core/db/backends/ado_mssql.py (modified) (1 diff)
- django/branches/i18n/django/core/db/backends/mysql.py (modified) (2 diffs)
- django/branches/i18n/django/core/db/backends/postgresql.py (modified) (1 diff)
- django/branches/i18n/django/core/db/backends/sqlite3.py (modified) (1 diff)
- django/branches/i18n/django/core/db/__init__.py (modified) (2 diffs)
- django/branches/i18n/django/core/template/defaultfilters.py (modified) (1 diff)
- django/branches/i18n/django/core/template/defaulttags.py (modified) (2 diffs)
- django/branches/i18n/django/middleware/sessions.py (modified) (1 diff)
- django/branches/i18n/django/utils/cache.py (modified) (2 diffs)
- django/branches/i18n/django/utils/httpwrappers.py (modified) (1 diff)
- django/branches/i18n/docs/cache.txt (modified) (1 diff)
- django/branches/i18n/docs/db-api.txt (modified) (3 diffs)
- django/branches/i18n/docs/legacy_databases.txt (modified) (2 diffs)
- django/branches/i18n/docs/request_response.txt (modified) (2 diffs)
- django/branches/i18n/docs/sessions.txt (modified) (2 diffs)
- django/branches/i18n/docs/tutorial04.txt (modified) (1 diff)
- django/branches/i18n/tests/testapp/models/basic.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/i18n/django/core/db/backends/ado_mssql.py
r956 r1067 111 111 raise NotImplementedError 112 112 113 def quote_name(name): 114 # TODO: Figure out how MS-SQL quotes database identifiers. 115 return name 116 113 117 OPERATOR_MAPPING = { 114 118 'exact': '=', django/branches/i18n/django/core/db/backends/mysql.py
r869 r1067 123 123 raise NotImplementedError 124 124 125 def quote_name(name): 126 if name.startswith("`") and name.endswith("`"): 127 return name # Quoting once is enough. 128 return "`%s`" % name 129 125 130 OPERATOR_MAPPING = { 126 131 'exact': '=', 127 132 'iexact': 'LIKE', 128 'contains': 'LIKE ',133 'contains': 'LIKE BINARY', 129 134 'icontains': 'LIKE', 130 135 'ne': '!=', … … 133 138 'lt': '<', 134 139 'lte': '<=', 135 'startswith': 'LIKE ',136 'endswith': 'LIKE ',140 'startswith': 'LIKE BINARY', 141 'endswith': 'LIKE BINARY', 137 142 'istartswith': 'LIKE', 138 143 'iendswith': 'LIKE', django/branches/i18n/django/core/db/backends/postgresql.py
r869 r1067 117 117 return relations 118 118 119 def quote_name(name): 120 if name.startswith('"') and name.endswith('"'): 121 return name # Quoting once is enough. 122 return '"%s"' % name 123 119 124 # Register these custom typecasts, because Django expects dates/times to be 120 125 # in Python's native (standard-library) datetime/time format, whereas psycopg django/branches/i18n/django/core/db/backends/sqlite3.py
r853 r1067 125 125 raise NotImplementedError 126 126 127 def quote_name(name): 128 if name.startswith('"') and name.endswith('"'): 129 return name # Quoting once is enough. 130 return '"%s"' % name 131 127 132 # Operators and fields ######################################################## 128 133 django/branches/i18n/django/core/db/__init__.py
r615 r1067 2 2 This is the core database connection. 3 3 4 All CMScode assumes database SELECT statements cast the resulting values as such:4 All Django code assumes database SELECT statements cast the resulting values as such: 5 5 * booleans are mapped to Python booleans 6 6 * dates are mapped to Python datetime.date objects 7 7 * times are mapped to Python datetime.time objects 8 8 * timestamps are mapped to Python datetime.datetime objects 9 10 Right now, we're handling this by using psycopg's custom typecast definitions.11 If we move to a different database module, we should ensure that it either12 performs the appropriate typecasting out of the box, or that it has hooks that13 let us do that.14 9 """ 15 10 … … 42 37 get_table_list = dbmod.get_table_list 43 38 get_relations = dbmod.get_relations 39 quote_name = dbmod.quote_name 44 40 OPERATOR_MAPPING = dbmod.OPERATOR_MAPPING 45 41 DATA_TYPES = dbmod.DATA_TYPES django/branches/i18n/django/core/template/defaultfilters.py
r1027 r1067 28 28 only if there's a point to be displayed 29 29 """ 30 f = float(text) 30 try: 31 f = float(text) 32 except ValueError: 33 return '' 31 34 m = f - int(f) 32 35 if m: django/branches/i18n/django/core/template/defaulttags.py
r1064 r1067 215 215 216 216 def render(self, context): 217 from django.conf.settings import DEBUG 217 218 if not include_is_allowed(self.filepath): 218 return '' # Fail silently for invalid includes. 219 if DEBUG: 220 return "[Didn't have permission to include file]" 221 else: 222 return '' # Fail silently for invalid includes. 219 223 try: 220 224 fp = open(self.filepath, 'r') … … 227 231 t = Template(output) 228 232 return t.render(context) 229 except TemplateSyntaxError: 230 return '' # Fail silently for invalid included templates. 233 except (TemplateSyntaxError, e): 234 if DEBUG: 235 return "[Included template had syntax error: %s]" % e 236 else: 237 return '' # Fail silently for invalid included templates. 231 238 return output 232 239 django/branches/i18n/django/middleware/sessions.py
r815 r1067 72 72 new_session = sessions.save(session_key, request.session._session, 73 73 datetime.datetime.now() + datetime.timedelta(seconds=SESSION_COOKIE_AGE)) 74 expires = datetime.datetime.strftime(datetime.datetime.utcnow() + datetime.timedelta(seconds=SESSION_COOKIE_AGE), "%a, %d-%b-%Y %H:%M:%S GMT") 74 75 response.set_cookie(SESSION_COOKIE_NAME, session_key, 75 max_age=SESSION_COOKIE_AGE, domain=SESSION_COOKIE_DOMAIN)76 max_age=SESSION_COOKIE_AGE, expires=expires, domain=SESSION_COOKIE_DOMAIN) 76 77 return response django/branches/i18n/django/utils/cache.py
r1043 r1067 23 23 24 24 cc_delim_re = re.compile(r'\s*,\s*') 25 25 26 def patch_cache_control(response, **kwargs): 26 27 """ … … 28 29 keyword arguments to it. The transformation is as follows: 29 30 30 - all keyword parameter names are turned to lowercase and31 a ll _ will be translated to -32 - if the value of a parameter is True (exatly True, not just a33 true value), only the parameter name is added to the header 34 - all other parameters are added with their value, after applying35 str to it.31 * All keyword parameter names are turned to lowercase, and underscores 32 are converted to hyphens. 33 * If the value of a parameter is True (exactly True, not just a 34 true value), only the parameter name is added to the header. 35 * All other parameters are added with their value, after applying 36 str() to it. 36 37 """ 37 38 38 def dictitem(s): 39 39 t = s.split('=',1) django/branches/i18n/django/utils/httpwrappers.py
r787 r1067 173 173 return False 174 174 175 def set_cookie(self, key, value='', max_age=None, path='/', domain=None, secure=None):175 def set_cookie(self, key, value='', max_age=None, expires=None, path='/', domain=None, secure=None): 176 176 self.cookies[key] = value 177 for var in ('max_age', 'path', 'domain', 'secure' ):177 for var in ('max_age', 'path', 'domain', 'secure', 'expires'): 178 178 val = locals()[var] 179 179 if val is not None: django/branches/i18n/docs/cache.txt
r1027 r1067 273 273 .. _`HTTP Vary headers`: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44 274 274 275 Controlling cache: Using Vary headers 276 ===================================== 277 278 Another problem with caching is the privacy of data, and the question where data can 279 be stored in a cascade of caches. A user usually faces two kinds of caches: his own 280 browser cache (a private cache) and his providers cache (a public cache). A public cache 281 is used by multiple users and controlled by someone else. This poses problems with private 282 (in the sense of sensitive) data - you don't want your social security number or your 283 banking account numbers stored in some public cache. So web applications need a way 284 to tell the caches what data is private and what is public. 285 286 Other aspects are the definition how long a page should be cached at max, or wether the 287 cache should allways check for newer versions and only deliver the cache content when 288 there were no changes (some caches might deliver cached content even if the server page 289 changed - just because the cache copy isn't yet expired). 290 291 So there are a multitude of options you can control for your pages. This is where the 292 Cache-Control header (more infos in `HTTP Cache-Control headers`_) comes in. The usage 293 is quite simple:: 294 295 @cache_control(private=True, must_revalidate=True, max_age=3600) 296 def my_view(request): 297 ... 298 299 This would define the view as private, to be revalidated on every access and cache 300 copies will only be stored for 3600 seconds at max. 301 302 The caching middleware already set's this header up with a max-age of the CACHE_MIDDLEWARE_SETTINGS 303 setting. And the cache_page decorator does the same. The cache_control decorator correctly merges 304 different values into one big header, though. But you should take into account that middlewares 305 might overwrite some of your headers or set their own defaults if you don't give that header yourself. 306 307 .. _`HTTP Cache-Control headers`: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 275 Controlling cache: Using other headers 276 ====================================== 277 278 Another problem with caching is the privacy of data and the question of where 279 data should be stored in a cascade of caches. 280 281 A user usually faces two kinds of caches: his own browser cache (a private 282 cache) and his provider's cache (a public cache). A public cache is used by 283 multiple users and controlled by someone else. This poses problems with 284 sensitive data: You don't want, say, your banking-account number stored in a 285 public cache. So Web applications need a way to tell caches which data is 286 private and which is public. 287 288 The solution is to indicate a page's cache should be "private." To do this in 289 Django, use the ``cache_control`` view decorator. Example:: 290 291 from django.views.decorators.cache import cache_control 292 @cache_control(private=True) 293 def my_view(request): 294 ... 295 296 This decorator takes care of sending out the appropriate HTTP header behind the 297 scenes. 298 299 There are a few other ways to control cache parameters. For example, HTTP 300 allows applications to do the following: 301 302 * Define the maximum time a page should be cached. 303 * Specify whether a cache should always check for newer versions, only 304 delivering the cached content when there are no changes. (Some caches 305 might deliver cached content even if the server page changed -- simply 306 because the cache copy isn't yet expired.) 307 308 In Django, use the ``cache_control`` view decorator to specify these cache 309 parameters. In this example, ``cache_control`` tells caches to revalidate the 310 cache on every access and to store cached versions for, at most, 3600 seconds:: 311 312 from django.views.decorators.cache import cache_control 313 @cache_control(must_revalidate=True, max_age=3600) 314 def my_view(request): 315 ... 316 317 Any valid ``Cache-Control`` directive is valid in ``cache_control()``. For a 318 full list, see the `Cache-Control spec`_. Just pass the directives as keyword 319 arguments to ``cache_control()``, substituting underscores for hyphens. For 320 directives that don't take an argument, set the argument to ``True``. 321 322 Examples: 323 324 * ``@cache_control(max_age=3600)`` turns into ``max-age=3600``. 325 * ``@cache_control(public=True)`` turns into ``public``. 326 327 (Note that the caching middleware already sets the cache header's max-age with 328 the value of the ``CACHE_MIDDLEWARE_SETTINGS`` setting. If you use a custom 329 ``max_age`` in a ``cache_control`` decorator, the decorator will take 330 precedence, and the header values will be merged correctly.) 331 332 .. _`Cache-Control spec`: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 308 333 309 334 Other optimizations django/branches/i18n/docs/db-api.txt
r844 r1067 162 162 contains Case-sensitive containment test: 163 163 ``polls.get_list(question__contains="spam")`` returns all polls 164 that contain "spam" in the question. (PostgreSQL only.MySQL165 doesn't support case-sensitive LIKE statements; ``contains``166 will act like ``icontains`` for MySQL.)164 that contain "spam" in the question. (PostgreSQL and MySQL 165 only. SQLite doesn't support case-sensitive LIKE statements; 166 ``contains`` will act like ``icontains`` for SQLite.) 167 167 icontains Case-insensitive containment test. 168 168 gt Greater than: ``polls.get_list(id__gt=4)``. … … 175 175 startswith Case-sensitive starts-with: 176 176 ``polls.get_list(question_startswith="Would")``. (PostgreSQL 177 only. MySQL doesn't support case-sensitive LIKE statements; 178 ``startswith`` will act like ``istartswith`` for MySQL.) 179 endswith Case-sensitive ends-with. (PostgreSQL only. MySQL doesn't 180 support case-sensitive LIKE statements; ``endswith`` will act 181 like ``iendswith`` for MySQL.) 177 and MySQL only. SQLite doesn't support case-sensitive LIKE 178 statements; ``startswith`` will act like ``istartswith`` for 179 SQLite.) 180 endswith Case-sensitive ends-with. (PostgreSQL and MySQL only.) 182 181 istartswith Case-insensitive starts-with. 183 182 iendswith Case-insensitive ends-with. … … 240 239 241 240 polls.get_list(order_by=['?']) 241 242 There's no way to specify whether ordering should be case sensitive. With 243 respect to case-sensitivity, Django will order results however your database 244 backend normally orders them. 242 245 243 246 Relationships (joins) django/branches/i18n/docs/legacy_databases.txt
r534 r1067 17 17 You'll need to tell Django what your database connection parameters are, and 18 18 what the name of the database is. Do that by editing these settings in your 19 settings file:19 `settings file`_: 20 20 21 * ``DATABASE_ENGINE`` 22 * ``DATABASE_USER`` 23 * ``DATABASE_PASSWORD`` 24 * ``DATABASE_NAME`` 25 * ``DATABASE_HOST`` 21 * `DATABASE_ENGINE`_ 22 * `DATABASE_USER`_ 23 * `DATABASE_PASSWORD`_ 24 * `DATABASE_NAME`_ 25 * `DATABASE_HOST`_ 26 * `DATABASE_PORT`_ 26 27 27 For more information on these settings see `Tutorial 1`_. 28 29 .. _Tutorial 1: http://www.djangoproject.com/documentation/tutorial1/ 28 .. _settings file: http://www.djangoproject.com/documentation/settings/ 29 .. _DATABASE_ENGINE: http://www.djangoproject.com/documentation/settings/#database-engine 30 .. _DATABASE_USER: http://www.djangoproject.com/documentation/settings/#database-user 31 .. _DATABASE_PASSWORD: http://www.djangoproject.com/documentation/settings/#database-password 32 .. _DATABASE_NAME: http://www.djangoproject.com/documentation/settings/#database-name 33 .. _DATABASE_HOST: http://www.djangoproject.com/documentation/settings/#database-host 34 .. _DATABASE_PORT: http://www.djangoproject.com/documentation/settings/#database-port 30 35 31 36 Auto-generate the models … … 73 78 * ``auth_users`` 74 79 * ``auth_messages`` 75 * ``auth_admin_log``76 80 * ``auth_groups_permissions`` 77 81 * ``auth_users_groups`` django/branches/i18n/docs/request_response.txt
r711 r1067 285 285 header with the given name. 286 286 287 ``set_cookie(key, value='', max_age=None, path='/', domain=None, secure=None)``287 ``set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None)`` 288 288 Sets a cookie. The parameters are the same as in the `cookie Morsel`_ 289 289 object in the Python standard library. … … 291 291 * ``max_age`` should be a number of seconds, or ``None`` (default) if 292 292 the cookie should last only as long as the client's browser session. 293 * ``expires`` should be a string in the format 294 ``"Wdy, DD-Mon-YY HH:MM:SS GMT"``. 293 295 * Use ``domain`` if you want to set a cross-domain cookie. For example, 294 296 ``domain=".lawrence.com"`` will set a cookie that is readable by django/branches/i18n/docs/sessions.txt
r869 r1067 159 159 {'user_id': 42} 160 160 161 Session cookies 162 =============== 163 164 A few `Django settings`_ give you control over the session cookie: 165 166 SESSION_COOKIE_AGE 167 ------------------ 168 169 Default: ``1209600`` (2 weeks, in seconds) 170 171 The age of session cookies, in seconds. 172 173 SESSION_COOKIE_DOMAIN 174 --------------------- 175 176 Default: ``None`` 177 178 The domain to use for session cookies. Set this to a string such as 179 ``".lawrence.com"`` for cross-domain cookies, or use ``None`` for a standard 180 domain cookie. 181 182 SESSION_COOKIE_NAME 183 ------------------- 184 185 Default: ``'hotclub'`` 186 187 The name of the cookie to use for sessions. This can be whatever you want. 188 189 ``'hotclub'`` is a reference to the Hot Club of France, the band Django 190 Reinhardt played in. 191 192 .. _Django settings: http://www.djangoproject.com/documentation/settings/ 193 161 194 Technical details 162 195 ================= … … 171 204 172 205 .. _`the pickle module`: http://www.python.org/doc/current/lib/module-pickle.html 206 207 Session IDs in URLs 208 =================== 209 210 The Django sessions framework is entirely, and solely, cookie-based. It does 211 not fall back to putting session IDs in URLs as a last resort, as PHP does. 212 This is an intentional design decision. Not only does that behavior make URLs 213 ugly, it makes your site vulnerable to session-ID theft via the "Referer" 214 header. django/branches/i18n/docs/tutorial04.txt
r869 r1067 214 214 ``poll`` becomes ``object``. 215 215 216 In the ``vote()`` view, change the template call from ``polls/detail`` to 217 ``polls/polls_detail``, and pass ``object`` in the context instead of ``poll``. 218 216 219 Finally, you can delete the ``index()``, ``detail()`` and ``results()`` views 217 220 from ``polls/views/polls.py``. We don't need them anymore. django/branches/i18n/tests/testapp/models/basic.py
r549 r1067 52 52 >>> articles.get_object(pub_date__year=2005) 53 53 <Article object> 54 >>> articles.get_object(pub_date__year=2005, pub_date__month=7) 55 <Article object> 56 >>> articles.get_object(pub_date__year=2005, pub_date__month=7, pub_date__day=28) 57 <Article object> 58 59 >>> articles.get_list(pub_date__year=2005) 60 [<Article object>] 61 >>> articles.get_list(pub_date__year=2004) 62 [] 63 >>> articles.get_list(pub_date__year=2005, pub_date__month=7) 64 [<Article object>] 54 65 55 66 # Django raises an ArticleDoesNotExist exception for get_object() … … 58 69 ... 59 70 ArticleDoesNotExist: Article does not exist for {'id__exact': 2} 71 72 >>> articles.get_object(pub_date__year=2005, pub_date__month=8) 73 Traceback (most recent call last): 74 ... 75 ArticleDoesNotExist: Article does not exist for ... 60 76 61 77 # Lookup by a primary key is the most common case, so Django provides a
