Changeset 1773
- Timestamp:
- 12/23/05 22:39:59 (3 years ago)
- Files:
-
- django/trunk/django/conf/global_settings.py (modified) (1 diff)
- django/trunk/django/core/extensions.py (modified) (2 diffs)
- django/trunk/django/views/generic/create_update.py (modified) (8 diffs)
- django/trunk/django/views/generic/date_based.py (modified) (11 diffs)
- django/trunk/django/views/generic/list_detail.py (modified) (5 diffs)
- django/trunk/docs/authentication.txt (modified) (2 diffs)
- django/trunk/docs/generic_views.txt (modified) (3 diffs)
- django/trunk/docs/settings.txt (modified) (1 diff)
- django/trunk/docs/templates_python.txt (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/conf/global_settings.py
r1584 r1773 101 101 ) 102 102 103 # List of processors used by DjangoContext to populate the context. 104 # Each one should be a callable that takes the request object as its 105 # only parameter and returns a dictionary to add to the context. 106 TEMPLATE_CONTEXT_PROCESSORS = ( 107 'django.core.context_processors.auth', 108 'django.core.context_processors.debug', 109 'django.core.context_processors.i18n', 110 ) 111 103 112 # URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a 104 113 # trailing slash. django/trunk/django/core/extensions.py
r1068 r1773 3 3 # for convenience's sake. 4 4 5 from django.core.exceptions import Http404, ObjectDoesNotExist5 from django.core.exceptions import Http404, ImproperlyConfigured, ObjectDoesNotExist 6 6 from django.core.template import Context, loader 7 from django.conf.settings import DEBUG, INTERNAL_IPS7 from django.conf.settings import TEMPLATE_CONTEXT_PROCESSORS 8 8 from django.utils.httpwrappers import HttpResponse 9 10 _standard_context_processors = None 11 12 # This is a function rather than module-level procedural code because we only 13 # want it to execute if somebody uses DjangoContext. 14 def get_standard_processors(): 15 global _standard_context_processors 16 if _standard_context_processors is None: 17 processors = [] 18 for path in TEMPLATE_CONTEXT_PROCESSORS: 19 i = path.rfind('.') 20 module, attr = path[:i], path[i+1:] 21 try: 22 mod = __import__(module, '', '', [attr]) 23 except ImportError, e: 24 raise ImproperlyConfigured, 'Error importing request processor module %s: "%s"' % (module, e) 25 try: 26 func = getattr(mod, attr) 27 except AttributeError: 28 raise ImproperlyConfigured, 'Module "%s" does not define a "%s" callable request processor' % (module, attr) 29 processors.append(func) 30 _standard_context_processors = tuple(processors) 31 return _standard_context_processors 9 32 10 33 def render_to_response(*args, **kwargs): … … 26 49 class DjangoContext(Context): 27 50 """ 28 This subclass of template.Context automatically populates 'user' and 29 'messages' in the context. 51 This subclass of template.Context automatically populates itself using 52 the processors defined in TEMPLATE_CONTEXT_PROCESSORS. 53 Additional processors can be specified as a list of callables 54 using the "processors" keyword argument. 30 55 """ 31 def __init__(self, request, dict=None ):56 def __init__(self, request, dict=None, processors=None): 32 57 Context.__init__(self, dict) 33 self['user'] = request.user 34 self['messages'] = request.user.get_and_delete_messages() 35 self['perms'] = PermWrapper(request.user) 36 from django.conf import settings 37 self['LANGUAGES'] = settings.LANGUAGES 38 if hasattr(request, 'LANGUAGE_CODE'): 39 self['LANGUAGE_CODE'] = request.LANGUAGE_CODE 58 if processors is None: 59 processors = () 40 60 else: 41 self['LANGUAGE_CODE'] = settings.LANGUAGE_CODE 42 if DEBUG and request.META.get('REMOTE_ADDR') in INTERNAL_IPS: 43 self['debug'] = True 44 from django.core import db 45 self['sql_queries'] = db.db.queries 61 processors = tuple(processors) 62 for processor in get_standard_processors() + processors: 63 self.update(processor(request)) 46 64 47 65 # PermWrapper and PermLookupDict proxy the permissions system into objects that django/trunk/django/views/generic/create_update.py
r1684 r1773 4 4 from django.core import formfields, meta 5 5 from django.views.auth.login import redirect_to_login 6 from django.core.extensions import DjangoContext as Context6 from django.core.extensions import DjangoContext 7 7 from django.core.paginator import ObjectPaginator, InvalidPage 8 8 from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect … … 10 10 11 11 def create_object(request, app_label, module_name, template_name=None, 12 template_loader=loader, extra_context={},13 post_save_redirect=None, login_required=False, follow=None):12 template_loader=loader, extra_context={}, post_save_redirect=None, 13 login_required=False, follow=None, context_processors=None): 14 14 """ 15 15 Generic object-creation function. … … 61 61 template_name = "%s/%s_form" % (app_label, module_name) 62 62 t = template_loader.get_template(template_name) 63 c = Context(request, {64 'form' : form,65 } )63 c = DjangoContext(request, { 64 'form': form, 65 }, context_processors) 66 66 for key, value in extra_context.items(): 67 67 if callable(value): … … 72 72 73 73 def update_object(request, app_label, module_name, object_id=None, slug=None, 74 slug_field=None, template_name=None, template_loader=loader,75 extra_lookup_kwargs={}, extra_context={}, post_save_redirect=None,76 login_required=False, follow=None):74 slug_field=None, template_name=None, template_loader=loader, 75 extra_lookup_kwargs={}, extra_context={}, post_save_redirect=None, 76 login_required=False, follow=None, context_processors=None): 77 77 """ 78 78 Generic object-update function. … … 132 132 template_name = "%s/%s_form" % (app_label, module_name) 133 133 t = template_loader.get_template(template_name) 134 c = Context(request, {135 'form' : form,136 'object' : object,137 } )134 c = DjangoContext(request, { 135 'form': form, 136 'object': object, 137 }, context_processors) 138 138 for key, value in extra_context.items(): 139 139 if callable(value): … … 146 146 147 147 def delete_object(request, app_label, module_name, post_delete_redirect, 148 object_id=None, slug=None, slug_field=None, template_name=None,149 template_loader=loader, extra_lookup_kwargs={},150 extra_context={}, login_required=False):148 object_id=None, slug=None, slug_field=None, template_name=None, 149 template_loader=loader, extra_lookup_kwargs={}, extra_context={}, 150 login_required=False, context_processors=None): 151 151 """ 152 152 Generic object-delete function. … … 189 189 template_name = "%s/%s_confirm_delete" % (app_label, module_name) 190 190 t = template_loader.get_template(template_name) 191 c = Context(request, {192 'object' : object,193 } )191 c = DjangoContext(request, { 192 'object': object, 193 }, context_processors) 194 194 for key, value in extra_context.items(): 195 195 if callable(value): … … 200 200 populate_xheaders(request, response, app_label, module_name, getattr(object, object._meta.pk.name)) 201 201 return response 202 django/trunk/django/views/generic/date_based.py
r1684 r1773 1 1 from django.core.template import loader 2 2 from django.core.exceptions import Http404, ObjectDoesNotExist 3 from django.core.extensions import DjangoContext as Context3 from django.core.extensions import DjangoContext 4 4 from django.core.xheaders import populate_xheaders 5 5 from django.models import get_module … … 8 8 9 9 def archive_index(request, app_label, module_name, date_field, num_latest=15, 10 template_name=None, template_loader=loader,11 extra_lookup_kwargs={}, extra_context={}, allow_empty=False):10 template_name=None, template_loader=loader, extra_lookup_kwargs={}, 11 extra_context={}, allow_empty=False, context_processors=None): 12 12 """ 13 13 Generic top-level archive of date-based objects. … … 39 39 template_name = "%s/%s_archive" % (app_label, module_name) 40 40 t = template_loader.get_template(template_name) 41 c = Context(request, {41 c = DjangoContext(request, { 42 42 'date_list' : date_list, 43 43 'latest' : latest, 44 } )44 }, context_processors) 45 45 for key, value in extra_context.items(): 46 46 if callable(value): … … 51 51 52 52 def archive_year(request, year, app_label, module_name, date_field, 53 template_name=None, template_loader=loader,54 extra_lookup_kwargs={}, extra_context={}):53 template_name=None, template_loader=loader, extra_lookup_kwargs={}, 54 extra_context={}, context_processors=None): 55 55 """ 56 56 Generic yearly archive view. … … 76 76 template_name = "%s/%s_archive_year" % (app_label, module_name) 77 77 t = template_loader.get_template(template_name) 78 c = Context(request, {78 c = DjangoContext(request, { 79 79 'date_list': date_list, 80 80 'year': year, 81 } )81 }, context_processors) 82 82 for key, value in extra_context.items(): 83 83 if callable(value): … … 88 88 89 89 def archive_month(request, year, month, app_label, module_name, date_field, 90 month_format='%b', template_name=None, template_loader=loader,91 extra_lookup_kwargs={}, extra_context={}):90 month_format='%b', template_name=None, template_loader=loader, 91 extra_lookup_kwargs={}, extra_context={}, context_processors=None): 92 92 """ 93 93 Generic monthly archive view. … … 124 124 template_name = "%s/%s_archive_month" % (app_label, module_name) 125 125 t = template_loader.get_template(template_name) 126 c = Context(request, {126 c = DjangoContext(request, { 127 127 'object_list': object_list, 128 128 'month': date, 129 } )129 }, context_processors) 130 130 for key, value in extra_context.items(): 131 131 if callable(value): … … 136 136 137 137 def archive_day(request, year, month, day, app_label, module_name, date_field, 138 month_format='%b', day_format='%d', template_name=None,139 template_loader=loader, extra_lookup_kwargs={},140 extra_context={}, allow_empty=False):138 month_format='%b', day_format='%d', template_name=None, 139 template_loader=loader, extra_lookup_kwargs={}, extra_context={}, 140 allow_empty=False, context_processors=None): 141 141 """ 142 142 Generic daily archive view. … … 173 173 template_name = "%s/%s_archive_day" % (app_label, module_name) 174 174 t = template_loader.get_template(template_name) 175 c = Context(request, {175 c = DjangoContext(request, { 176 176 'object_list': object_list, 177 177 'day': date, 178 178 'previous_day': date - datetime.timedelta(days=1), 179 179 'next_day': (date < datetime.date.today()) and (date + datetime.timedelta(days=1)) or None, 180 } )180 }, context_processors) 181 181 for key, value in extra_context.items(): 182 182 if callable(value): … … 199 199 200 200 def object_detail(request, year, month, day, app_label, module_name, date_field, 201 month_format='%b', day_format='%d', object_id=None, slug=None,202 slug_field=None, template_name=None, template_name_field=None,203 template_loader=loader, extra_lookup_kwargs={},204 extra_context={}):201 month_format='%b', day_format='%d', object_id=None, slug=None, 202 slug_field=None, template_name=None, template_name_field=None, 203 template_loader=loader, extra_lookup_kwargs={}, extra_context={}, 204 context_processors=None): 205 205 """ 206 206 Generic detail view from year/month/day/slug or year/month/day/id structure. … … 242 242 else: 243 243 t = template_loader.get_template(template_name) 244 c = Context(request, {244 c = DjangoContext(request, { 245 245 'object': object, 246 } )246 }, context_processors) 247 247 for key, value in extra_context.items(): 248 248 if callable(value): django/trunk/django/views/generic/list_detail.py
r1684 r1773 3 3 from django.utils.httpwrappers import HttpResponse 4 4 from django.core.xheaders import populate_xheaders 5 from django.core.extensions import DjangoContext as Context5 from django.core.extensions import DjangoContext 6 6 from django.core.paginator import ObjectPaginator, InvalidPage 7 7 from django.core.exceptions import Http404, ObjectDoesNotExist 8 8 9 9 def object_list(request, app_label, module_name, paginate_by=None, allow_empty=False, 10 template_name=None, template_loader=loader,11 extra_lookup_kwargs={}, extra_context={}):10 template_name=None, template_loader=loader, extra_lookup_kwargs={}, 11 extra_context={}, context_processors=None): 12 12 """ 13 13 Generic list of objects. … … 49 49 raise Http404 50 50 page = int(page) 51 c = Context(request, {51 c = DjangoContext(request, { 52 52 'object_list': object_list, 53 53 'is_paginated': paginator.pages > 1, … … 60 60 'pages': paginator.pages, 61 61 'hits' : paginator.hits, 62 } )62 }, context_processors) 63 63 else: 64 64 object_list = mod.get_list(**lookup_kwargs) 65 c = Context(request, {65 c = DjangoContext(request, { 66 66 'object_list': object_list, 67 67 'is_paginated': False 68 } )68 }, context_processors) 69 69 if len(object_list) == 0 and not allow_empty: 70 70 raise Http404 … … 80 80 81 81 def object_detail(request, app_label, module_name, object_id=None, slug=None, 82 slug_field=None, template_name=None, template_name_field=None,83 template_loader=loader, extra_lookup_kwargs={},84 extra_context={}):82 slug_field=None, template_name=None, template_name_field=None, 83 template_loader=loader, extra_lookup_kwargs={}, extra_context={}, 84 context_processors=None): 85 85 """ 86 86 Generic list of objects. … … 111 111 else: 112 112 t = template_loader.get_template(template_name) 113 c = Context(request, {113 c = DjangoContext(request, { 114 114 'object': object, 115 } )115 }, context_processors) 116 116 for key, value in extra_context.items(): 117 117 if callable(value): django/trunk/docs/authentication.txt
r1440 r1773 439 439 `template context`_ when you use ``DjangoContext``. 440 440 441 .. admonition:: Technicality 442 443 Technically, these variables are only made available in the template context 444 if you use ``DjangoContext`` *and* your ``TEMPLATE_CONTEXT_PROCESSORS`` 445 setting contains ``"django.core.context_processors.auth"``, which is default. 446 For more, see the `DjangoContext docs`_. 447 448 .. _DjangoContext docs: http://www.djangoproject.com/documentation/templates_python/#subclassing-context-djangocontext 449 441 450 Users 442 451 ----- … … 455 464 456 465 The currently logged-in user's permissions are stored in the template variable 457 ``{{ perms }}``. This is an instance of ``django.core. extensions.PermWrapper``,466 ``{{ perms }}``. This is an instance of ``django.core.context_processors.PermWrapper``, 458 467 which is a template-friendly proxy of permissions. 459 468 django/trunk/docs/generic_views.txt
r1510 r1773 129 129 ``extra_context`` A dictionary of extra data to put into the 130 130 template's context. 131 132 ``processors`` **New in Django development version.** A tuple of 133 processors to apply to the ``DjangoContext`` of 134 this view's template. See the `DjangoContext docs`_ 131 135 ======================= ================================================== 132 136 133 .. _`database API docs`: http://www.djangoproject.com/documentation/db_api/ 137 .. _database API docs: http://www.djangoproject.com/documentation/db_api/ 138 .. _DjangoContext docs: http://www.djangoproject.com/documentation/templates_python/#subclassing-context-djangocontext 134 139 135 140 The date-based generic functions are: … … 248 253 object page. 249 254 250 All these views take the same threeoptional arguments as the date-based ones255 All these views take the same four optional arguments as the date-based ones 251 256 -- and, clearly, they don't accept the ``date_field`` argument. 252 257 … … 372 377 object 373 378 The object about to be deleted 374 django/trunk/docs/settings.txt
r1585 r1773 548 548 database can manage content for multiple sites. 549 549 550 TEMPLATE_CONTEXT_PROCESSORS 551 --------------------------- 552 553 Default:: 554 555 ("django.core.context_processors.auth", 556 "django.core.context_processors.debug", 557 "django.core.context_processors.i18n") 558 559 **Only available in Django development version.** 560 561 A tuple of callables that are used to populate the context in ``DjangoContext``. 562 These callables take a request object as their argument and return a dictionary 563 of items to be merged into the context. 564 550 565 TEMPLATE_DEBUG 551 566 -------------- django/trunk/docs/templates_python.txt
r1461 r1773 241 241 Django comes with a special ``Context`` class, 242 242 ``django.core.extensions.DjangoContext``, that acts slightly differently than 243 the normal ``django.core.template.Context``. It takes an ``HttpRequest`` object 244 as its first argument, and it automatically populates the context with a few 245 variables: 243 the normal ``django.core.template.Context``. The first difference is that takes 244 an `HttpRequest object`_ as its first argument. For example:: 245 246 c = DjangoContext(request, { 247 'foo': 'bar', 248 } 249 250 The second difference is that it automatically populates the context with a few 251 variables, according to your `TEMPLATE_CONTEXT_PROCESSORS setting`_. 252 253 The ``TEMPLATE_CONTEXT_PROCESSORS`` setting is a tuple of callables that take a 254 request object as their argument and return a dictionary of items to be merged 255 into the context. By default, ``TEMPLATE_CONTEXT_PROCESSORS`` is set to:: 256 257 ("django.core.context_processors.auth", 258 "django.core.context_processors.debug", 259 "django.core.context_processors.i18n") 260 261 Each processor is applied in order. That means, if one processor adds a 262 variable to the context and a second processor adds a variable with the same 263 name, the second will override the first. The default processors are explained 264 below. 265 266 Also, you can give ``DjangoContext`` a list of additional processors, using the 267 optional, third positional argument, ``processors``. In this example, the 268 ``DjangoContext`` instance gets a ``ip_address`` variable:: 269 270 def ip_address_processor(request): 271 return {'ip_address': request.META['REMOTE_ADDR']} 272 273 def some_view(request): 274 # ... 275 return DjangoContext({ 276 'foo': 'bar', 277 }, [ip_address_processor]) 278 279 Note: The concept of template-context processors is new in the Django 280 development version. In Django 0.90, ``DjangoContext`` automatically populates 281 the context with all of the values explained below, but it's not possible to 282 add and remove processors. 283 284 Here's what each of the default processors does: 285 286 .. _HttpRequest object: http://www.djangoproject.com/documentation/request_response/#httprequest-objects 287 .. _TEMPLATE_CONTEXT_PROCESSORS setting: http://www.djangoproject.com/documentation/settings/#template-context_processors 288 289 django.core.context_processors.auth 290 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 291 292 If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every 293 ``DjangoContext`` will contain these three variables: 246 294 247 295 * ``user`` -- An ``auth.User`` instance representing the currently … … 250 298 * ``messages`` -- A list of ``auth.Message`` objects for the currently 251 299 logged-in user. 252 * ``perms`` -- An instance of ``django.core. extensions.PermWrapper``,300 * ``perms`` -- An instance of ``django.core.context_processors.PermWrapper``, 253 301 representing the permissions that the currently logged-in user has. See 254 302 the `permissions docs`_. 255 303 256 Also, if your ``DEBUG`` setting is set to ``True``, every ``DjangoContext`` 257 instance has the following two extra variables: 304 .. _user authentication docs: http://www.djangoproject.com/documentation/models/authentication/#users 305 .. _permissions docs: http://www.djangoproject.com/documentation/models/authentication/#permissions 306 307 django.core.context_processors.debug 308 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 309 310 If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every 311 ``DjangoContext`` will contain these two variables -- but only if your 312 ``DEBUG`` setting is set to ``True`` and the request's IP address 313 (``request.META['REMOTE_ADDR']``) is in the ``INTERNAL_IPS`` setting: 258 314 259 315 * ``debug`` -- ``True``. You can use this in templates to test whether … … 262 318 representing every SQL query that has happened so far during the request 263 319 and how long it took. The list is in order by query. 320 321 django.core.context_processors.i18n 322 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 323 324 If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every 325 ``DjangoContext`` will contain these two variables: 326 327 * ``LANGUAGES`` -- The value of the `LANGUAGES setting`_. 328 * ``LANGUAGE_CODE`` -- ``request.LANGUAGE_CODE``, if it exists. Otherwise, 329 the value of the `LANGUAGE_CODE setting`_. 330 331 See the `internationalization docs`_ for more. 332 333 .. _LANGUAGES setting: http://www.djangoproject.com/documentation/settings/#languages 334 .. _LANGUAGE_CODE setting: http://www.djangoproject.com/documentation/settings/#language-code 335 .. _internationalization docs: http://www.djangoproject.com/documentation/i18n/ 336 337 Subclassing Context: Custom subclasses 338 -------------------------------------- 264 339 265 340 Feel free to subclass ``Context`` yourself if you find yourself wanting to give … … 281 356 * You'll have to be careful not to set the variable ``current_time`` when 282 357 you populate this context. If you do, you'll override the other one. 283 284 .. _user authentication docs: http://www.djangoproject.com/documentation/models/authentication/#users285 .. _permissions docs: http://www.djangoproject.com/documentation/models/authentication/#permissions286 358 287 359 Loading templates
