Changeset 1027
- Timestamp:
- 10/30/05 18:13:29 (3 years ago)
- Files:
-
- django/branches/i18n/django/bin/django-admin.py (modified) (2 diffs)
- django/branches/i18n/django/conf/global_settings.py (modified) (1 diff)
- django/branches/i18n/django/contrib/admin/media/js/urlify.js (modified) (1 diff)
- django/branches/i18n/django/contrib/admin/views/doc.py (modified) (1 diff)
- django/branches/i18n/django/contrib/admin/views/main.py (modified) (1 diff)
- django/branches/i18n/django/core/cache.py (modified) (2 diffs)
- django/branches/i18n/django/core/formfields.py (modified) (3 diffs)
- django/branches/i18n/django/core/handlers/base.py (modified) (1 diff)
- django/branches/i18n/django/core/management.py (modified) (1 diff)
- django/branches/i18n/django/core/template/defaultfilters.py (modified) (2 diffs)
- django/branches/i18n/django/utils/autoreload.py (modified) (1 diff)
- django/branches/i18n/django/utils/cache.py (modified) (2 diffs)
- django/branches/i18n/django/views/decorators/auth.py (modified) (2 diffs)
- django/branches/i18n/django/views/decorators/cache.py (modified) (1 diff)
- django/branches/i18n/django/views/decorators/http.py (modified) (1 diff)
- django/branches/i18n/django/views/defaults.py (modified) (3 diffs)
- django/branches/i18n/docs/cache.txt (modified) (2 diffs)
- django/branches/i18n/docs/model-api.txt (modified) (2 diffs)
- django/branches/i18n/tests/othertests/defaultfilters.py (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/i18n/django/bin/django-admin.py
r1013 r1027 20 20 'inspectdb': management.inspectdb, 21 21 'install': management.install, 22 'installperms': management.installperms, 22 23 'runserver': management.runserver, 23 24 'sql': management.get_sql_create, … … 33 34 } 34 35 35 NO_SQL_TRANSACTION = ('adminindex', 'createcachetable', 'dbcheck', 'install', ' sqlindexes')36 NO_SQL_TRANSACTION = ('adminindex', 'createcachetable', 'dbcheck', 'install', 'installperms', 'sqlindexes') 36 37 37 38 def get_usage(): django/branches/i18n/django/conf/global_settings.py
r1001 r1027 84 84 # documentation. 85 85 TEMPLATE_LOADERS = ( 86 # 'django.core.template.loaders.app_directories.load_template_source',87 86 'django.core.template.loaders.filesystem.load_template_source', 87 'django.core.template.loaders.app_directories.load_template_source', 88 88 # 'django.core.template.loaders.eggs.load_template_source', 89 89 ) django/branches/i18n/django/contrib/admin/media/js/urlify.js
r979 r1027 10 10 s = s.replace(/[^\w\s-]/g, ''); // remove unneeded chars 11 11 s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces 12 s = s.replace(/\s+/g, ' _'); // convert spaces to underscores12 s = s.replace(/\s+/g, '-'); // convert spaces to hyphens 13 13 s = s.toLowerCase(); // convert to lowercase 14 14 return s.substring(0, num_chars);// trim to first num_chars chars django/branches/i18n/django/contrib/admin/views/doc.py
r960 r1027 289 289 def get_readable_field_data_type(field): 290 290 # ForeignKey is a special case. Use the field type of the relation. 291 if field. __class__.__name__== 'ForeignKey':291 if field.get_internal_type() == 'ForeignKey': 292 292 field = field.rel.get_related_field() 293 return DATA_TYPE_MAPPING[field. __class__.__name__] % field.__dict__293 return DATA_TYPE_MAPPING[field.get_internal_type()] % field.__dict__ 294 294 295 295 def extract_views_from_urlpatterns(urlpatterns, base=''): django/branches/i18n/django/contrib/admin/views/main.py
r956 r1027 557 557 seen_collapse = True 558 558 javascript_imports.append('%sjs/admin/CollapsedFieldsets.js' % ADMIN_MEDIA_PREFIX) 559 try:560 for field_list in options['fields']:559 for field_list in options['fields']: 560 try: 561 561 for f in field_list: 562 562 if f.rel and isinstance(f, meta.ManyToManyField) and f.rel.filter_interface: 563 563 javascript_imports.extend(['%sjs/SelectBox.js' % ADMIN_MEDIA_PREFIX, '%sjs/SelectFilter2.js' % ADMIN_MEDIA_PREFIX]) 564 564 raise StopIteration 565 except StopIteration:566 break565 except StopIteration: 566 break 567 567 for j in javascript_imports: 568 568 t.append('<script type="text/javascript" src="%s"></script>' % j) django/branches/i18n/django/core/cache.py
r844 r1027 14 14 15 15 memcached://127.0.0.1:11211/ A memcached backend; the server is running 16 on localhost port 11211. 16 on localhost port 11211. You can use 17 multiple memcached servers by separating 18 them with semicolons. 17 19 18 20 db://tablename/ A database backend in a table named … … 135 137 def __init__(self, server, params): 136 138 _Cache.__init__(self, params) 137 self._cache = memcache.Client( [server])139 self._cache = memcache.Client(server.split(';')) 138 140 139 141 def get(self, key, default=None): django/branches/i18n/django/core/formfields.py
r853 r1027 216 216 217 217 class TextField(FormField): 218 input_type = "text" 218 219 def __init__(self, field_name, length=30, maxlength=None, is_required=False, validator_list=[]): 219 220 self.field_name = field_name … … 238 239 if isinstance(data, unicode): 239 240 data = data.encode(DEFAULT_CHARSET) 240 return '<input type=" text" id="%s" class="v%s%s" name="%s" size="%s" value="%s" %s/>' % \241 ( FORM_FIELD_ID_PREFIX + self.field_name, self.__class__.__name__, self.is_required and ' required' or '',241 return '<input type="%s" id="%s" class="v%s%s" name="%s" size="%s" value="%s" %s/>' % \ 242 (self.input_type, FORM_FIELD_ID_PREFIX + self.field_name, self.__class__.__name__, self.is_required and ' required' or '', 242 243 self.field_name, self.length, escape(data), maxlength) 243 244 … … 247 248 248 249 class PasswordField(TextField): 249 def render(self, data): 250 # value is always blank because we never want to redisplay it 251 return '<input type="password" id="%s" class="v%s%s" name="%s" value="" />' % \ 252 (FORM_FIELD_ID_PREFIX + self.field_name, self.__class__.__name__, self.is_required and ' required' or '', 253 self.field_name) 250 input_type = "password" 254 251 255 252 class LargeTextField(TextField): django/branches/i18n/django/core/handlers/base.py
r956 r1027 48 48 from django.core.mail import mail_admins 49 49 from django.conf.settings import DEBUG, INTERNAL_IPS, ROOT_URLCONF 50 51 # Reset query list per request. 52 db.db.queries = [] 50 53 51 54 # Apply request middleware django/branches/i18n/django/core/management.py
r993 r1027 345 345 install.help_doc = "Executes ``sqlall`` for the given model module name(s) in the current database." 346 346 install.args = APP_ARGS 347 348 def installperms(mod): 349 "Installs any permissions for the given model, if needed." 350 from django.models.auth import permissions 351 from django.models.core import packages 352 num_added = 0 353 package = packages.get_object(pk=mod._MODELS[0]._meta.app_label) 354 for klass in mod._MODELS: 355 opts = klass._meta 356 for codename, name in _get_all_permissions(opts): 357 try: 358 permissions.get_object(name__exact=name, codename__exact=codename, package__label__exact=package.label) 359 except permissions.PermissionDoesNotExist: 360 p = permissions.Permission(name=name, package=package, codename=codename) 361 p.save() 362 print "Added permission '%r'." % p 363 num_added += 1 364 if not num_added: 365 print "No permissions were added, because all necessary permissions were already installed." 366 installperms.help_doc = "Installs any permissions for the given model module name(s), if needed." 367 installperms.args = APP_ARGS 347 368 348 369 def _start_helper(app_or_project, name, directory, other_name=''): django/branches/i18n/django/core/template/defaultfilters.py
r869 r1027 25 25 def floatformat(text, _): 26 26 """ 27 Displays a floating point number as 34.2 (with one decimal place) - but27 Displays a floating point number as 34.2 (with one decimal place) -- but 28 28 only if there's a point to be displayed 29 29 """ 30 f rom math import modf31 if not text:32 return ''33 if modf(float(text))[0] < 0.1:34 return text35 return "%.1f" % float(text)30 f = float(text) 31 m = f - int(f) 32 if m: 33 return '%.1f' % f 34 else: 35 return '%d' % int(f) 36 36 37 37 def linenumbers(value, _): … … 176 176 tags = [re.escape(tag) for tag in tags.split()] 177 177 tags_re = '(%s)' % '|'.join(tags) 178 starttag_re = re.compile( '<%s(>|(\s+[^>]*>))' % tags_re)178 starttag_re = re.compile(r'<%s(/?>|(\s+[^>]*>))' % tags_re) 179 179 endtag_re = re.compile('</%s>' % tags_re) 180 180 value = starttag_re.sub('', value) django/branches/i18n/django/utils/autoreload.py
r267 r1027 38 38 while RUN_RELOADER: 39 39 for filename in filter(lambda v: v, map(lambda m: getattr(m, "__file__", None), sys.modules.values())) + reloadFiles: 40 if not os.path.exists(filename): 41 continue # File might be in an egg, so it can't be reloaded. 40 42 if filename.endswith(".pyc"): 41 43 filename = filename[:-1] django/branches/i18n/django/utils/cache.py
r815 r1027 22 22 from django.core.cache import cache 23 23 24 cc_delim_re = re.compile(r'\s*,\s*') 25 def patch_cache_control(response, **kwargs): 26 """ 27 This function patches the Cache-Control header by adding all 28 keyword arguments to it. The transformation is as follows: 29 30 - all keyword parameter names are turned to lowercase and 31 all _ will be translated to - 32 - if the value of a parameter is True (exatly True, not just a 33 true value), only the parameter name is added to the header 34 - all other parameters are added with their value, after applying 35 str to it. 36 """ 37 38 def dictitem(s): 39 t = s.split('=',1) 40 if len(t) > 1: 41 return (t[0].lower().replace('-', '_'), t[1]) 42 else: 43 return (t[0].lower().replace('-', '_'), True) 44 45 def dictvalue(t): 46 if t[1] == True: 47 return t[0] 48 else: 49 return t[0] + '=' + str(t[1]) 50 51 if response.has_header('Cache-Control'): 52 print response['Cache-Control'] 53 cc = cc_delim_re.split(response['Cache-Control']) 54 print cc 55 cc = dict([dictitem(el) for el in cc]) 56 else: 57 cc = {} 58 for (k,v) in kwargs.items(): 59 cc[k.replace('_', '-')] = v 60 cc = ', '.join([dictvalue(el) for el in cc.items()]) 61 response['Cache-Control'] = cc 62 24 63 vary_delim_re = re.compile(r',\s*') 25 64 … … 44 83 if not response.has_header('Expires'): 45 84 response['Expires'] = expires.strftime('%a, %d %b %Y %H:%M:%S GMT') 46 if not response.has_header('Cache-Control'): 47 response['Cache-Control'] = 'max-age=%d' % cache_timeout 85 patch_cache_control(response, max_age=cache_timeout) 48 86 49 87 def patch_vary_headers(response, newheaders): django/branches/i18n/django/views/decorators/auth.py
r993 r1027 1 def user_passes_test( view_func,test_func):1 def user_passes_test(test_func): 2 2 """ 3 3 Decorator for views that checks that the user passes the given test, … … 5 5 that takes the user object and returns True if the user passes. 6 6 """ 7 from django.views.auth.login import redirect_to_login 8 def _checklogin(request, *args, **kwargs): 9 if test_func(request.user): 10 return view_func(request, *args, **kwargs) 11 return redirect_to_login(request.path) 12 return _checklogin 7 def _dec(view_func): 8 def _checklogin(request, *args, **kwargs): 9 from django.views.auth.login import redirect_to_login 10 if test_func(request.user): 11 return view_func(request, *args, **kwargs) 12 return redirect_to_login(request.path) 13 return _checklogin 14 return _dec 13 15 14 def login_required(view_func): 16 login_required = user_passes_test(lambda u: not u.is_anonymous()) 17 login_required.__doc__ = ( 15 18 """ 16 19 Decorator for views that checks that the user is logged in, redirecting 17 20 to the log-in page if necessary. 18 21 """ 19 return user_passes_test(lambda u: not u.is_anonymous())22 ) django/branches/i18n/django/views/decorators/cache.py
r815 r1027 11 11 account on caching -- just like the middleware does. 12 12 """ 13 import re 13 14 14 15 from django.utils.decorators import decorator_from_middleware 16 from django.utils.cache import patch_cache_control 15 17 from django.middleware.cache import CacheMiddleware 16 18 17 19 cache_page = decorator_from_middleware(CacheMiddleware) 20 21 def cache_control(**kwargs): 22 23 def _cache_controller(viewfunc): 24 25 def _cache_controlled(request, *args, **kw): 26 response = viewfunc(request, *args, **kw) 27 patch_cache_control(response, **kwargs) 28 return response 29 30 return _cache_controlled 31 32 return _cache_controller 33 django/branches/i18n/django/views/decorators/http.py
r815 r1027 1 1 """ 2 Decorator for views that supports conditional get on ETag and Last-Modified 3 headers. 2 Decorators for views based on HTTP headers. 4 3 """ 5 4 6 5 from django.utils.decorators import decorator_from_middleware 7 6 from django.middleware.http import ConditionalGetMiddleware 7 from django.utils.httpwrappers import HttpResponseForbidden 8 8 9 9 conditional_page = decorator_from_middleware(ConditionalGetMiddleware) 10 11 def require_http_methods(request_method_list): 12 """ 13 Decorator to make a view only accept particular request methods. Usage:: 14 15 @require_http_methods(["GET", "POST"]) 16 def my_view(request): 17 # I can assume now that only GET or POST requests make it this far 18 # ... 19 20 Note that request methods ARE case sensitive. 21 """ 22 def decorator(func): 23 def inner(request, *args, **kwargs): 24 method = request.META.get("REQUEST_METHOD", None) 25 if method not in request_method_list: 26 raise HttpResponseForbidden("REQUEST_METHOD '%s' not allowed" % method) 27 return func(request, *args, **kwargs) 28 return inner 29 return decorator 30 31 require_GET = require_http_methods(["GET"]) 32 require_GET.__doc__ = "Decorator to require that a view only accept the GET method." 33 34 require_POST = require_http_methods(["POST"]) 35 require_POST.__doc__ = "Decorator to require that a view only accept the POST method." django/branches/i18n/django/views/defaults.py
r910 r1027 1 1 from django.core.exceptions import Http404, ObjectDoesNotExist 2 2 from django.core.template import Context, loader 3 from django.models.core import sites 3 from django.models.core import sites, contenttypes 4 4 from django.utils import httpwrappers 5 5 6 6 def shortcut(request, content_type_id, object_id): 7 from django.models.core import contenttypes 7 """Redirect to an object's page based on a content-type ID and an object ID""" 8 # Look up the object, making sure it's got a get_absolute_url() function. 8 9 try: 9 10 content_type = contenttypes.get_object(pk=content_type_id) … … 15 16 except AttributeError: 16 17 raise Http404, "%s objects don't have get_absolute_url() methods" % content_type.name 18 19 # Try to figure out the object's domain so we can do a cross-site redirect 20 # if necessary 21 22 # If the object actually defines a domain, we're done. 17 23 if absurl.startswith('http://'): 18 24 return httpwrappers.HttpResponseRedirect(absurl) 25 19 26 object_domain = None 27 28 # Next, look for an many-to-many relationship to sites 20 29 if hasattr(obj, 'get_site_list'): 21 30 site_list = obj.get_site_list() 22 31 if site_list: 23 32 object_domain = site_list[0].domain 33 34 # Next, look for a many-to-one relationship to sites 24 35 elif hasattr(obj, 'get_site'): 25 36 try: … … 27 38 except sites.SiteDoesNotExist: 28 39 pass 29 try: 30 object_domain = sites.get_current().domain 31 except sites.SiteDoesNotExist: 32 pass 33 if not object_domain: 34 return httpwrappers.HttpResponseRedirect(absurl) 35 return httpwrappers.HttpResponseRedirect('http://%s%s' % (object_domain, absurl)) 40 41 # Then, fall back to the current site (if possible) 42 else: 43 try: 44 object_domain = sites.get_current().domain 45 except sites.SiteDoesNotExist: 46 # Finally, give up and use a URL without the domain name 47 return httpwrappers.HttpResponseRedirect(obj.get_absolute_url()) 48 return httpwrappers.HttpResponseRedirect('http://%s%s' % (object_domain, obj.get_absolute_url())) 36 49 37 50 def page_not_found(request): django/branches/i18n/docs/cache.txt
r815 r1027 30 30 ============================== =========================================== 31 31 memcached://127.0.0.1:11211/ A memcached backend; the server is running 32 on localhost port 11211. 32 on localhost port 11211. You can use 33 multiple memcached servers by separating 34 them with semicolons. 33 35 34 36 db://tablename/ A database backend in a table named … … 271 273 .. _`HTTP Vary headers`: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44 272 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 308 273 309 Other optimizations 274 310 =================== django/branches/i18n/docs/model-api.txt
r979 r1027 622 622 623 623 ``limit_choices_to`` See the description under ``ForeignKey`` above. 624 625 ``singular`` The singular name of the field. Use to name the ``get_*`` 626 methods: in the example above, Django gives the ``Pizza`` 627 objects a ``get_topping_list()`` method, where ``topping`` 628 is the default ``singular`` value derived from the lowercase 629 version of the class being linked to. Use the singular 630 parameter to change this, which is if you want one model to 631 have multiple ``ManyToMany`` relationships to another model. 624 632 ======================= ============================================================ 625 633 … … 751 759 Extra permissions to enter into the permissions table when creating this 752 760 object. Add, delete and change permissions are automatically created for 753 each object. This option specifies extra permissions:: 761 each object that has ``admin`` set. This example specifies an extra 762 permission, ``can_deliver_pizzas``:: 754 763 755 764 permissions = (("can_deliver_pizzas", "Can deliver pizzas"),) 756 765 757 This is a list o f 2-tuples of766 This is a list or tuple of 2-tuples in the format 758 767 ``(permission_code, human_readable_permission_name)``. 759 768
