Fixed #925 -- Added TEMPLATE_CONTEXT_PROCESSORS, which lets you specify processesors for DjangoContext. Thanks, Luke Plant
git-svn-id: http://code.djangoproject.com/svn/django/trunk@1773 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
d9269055c9
commit
49fd163a95
|
@ -100,6 +100,15 @@ TEMPLATE_LOADERS = (
|
||||||
# 'django.core.template.loaders.eggs.load_template_source',
|
# 'django.core.template.loaders.eggs.load_template_source',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# List of processors used by DjangoContext to populate the context.
|
||||||
|
# Each one should be a callable that takes the request object as its
|
||||||
|
# only parameter and returns a dictionary to add to the context.
|
||||||
|
TEMPLATE_CONTEXT_PROCESSORS = (
|
||||||
|
'django.core.context_processors.auth',
|
||||||
|
'django.core.context_processors.debug',
|
||||||
|
'django.core.context_processors.i18n',
|
||||||
|
)
|
||||||
|
|
||||||
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
|
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
|
||||||
# trailing slash.
|
# trailing slash.
|
||||||
# Examples: "http://foo.com/media/", "/media/".
|
# Examples: "http://foo.com/media/", "/media/".
|
||||||
|
|
|
@ -2,11 +2,34 @@
|
||||||
# of MVC. In other words, these functions/classes introduce controlled coupling
|
# of MVC. In other words, these functions/classes introduce controlled coupling
|
||||||
# for convenience's sake.
|
# for convenience's sake.
|
||||||
|
|
||||||
from django.core.exceptions import Http404, ObjectDoesNotExist
|
from django.core.exceptions import Http404, ImproperlyConfigured, ObjectDoesNotExist
|
||||||
from django.core.template import Context, loader
|
from django.core.template import Context, loader
|
||||||
from django.conf.settings import DEBUG, INTERNAL_IPS
|
from django.conf.settings import TEMPLATE_CONTEXT_PROCESSORS
|
||||||
from django.utils.httpwrappers import HttpResponse
|
from django.utils.httpwrappers import HttpResponse
|
||||||
|
|
||||||
|
_standard_context_processors = None
|
||||||
|
|
||||||
|
# This is a function rather than module-level procedural code because we only
|
||||||
|
# want it to execute if somebody uses DjangoContext.
|
||||||
|
def get_standard_processors():
|
||||||
|
global _standard_context_processors
|
||||||
|
if _standard_context_processors is None:
|
||||||
|
processors = []
|
||||||
|
for path in TEMPLATE_CONTEXT_PROCESSORS:
|
||||||
|
i = path.rfind('.')
|
||||||
|
module, attr = path[:i], path[i+1:]
|
||||||
|
try:
|
||||||
|
mod = __import__(module, '', '', [attr])
|
||||||
|
except ImportError, e:
|
||||||
|
raise ImproperlyConfigured, 'Error importing request processor module %s: "%s"' % (module, e)
|
||||||
|
try:
|
||||||
|
func = getattr(mod, attr)
|
||||||
|
except AttributeError:
|
||||||
|
raise ImproperlyConfigured, 'Module "%s" does not define a "%s" callable request processor' % (module, attr)
|
||||||
|
processors.append(func)
|
||||||
|
_standard_context_processors = tuple(processors)
|
||||||
|
return _standard_context_processors
|
||||||
|
|
||||||
def render_to_response(*args, **kwargs):
|
def render_to_response(*args, **kwargs):
|
||||||
return HttpResponse(loader.render_to_string(*args, **kwargs))
|
return HttpResponse(loader.render_to_string(*args, **kwargs))
|
||||||
load_and_render = render_to_response # For backwards compatibility.
|
load_and_render = render_to_response # For backwards compatibility.
|
||||||
|
@ -25,24 +48,19 @@ def get_list_or_404(mod, **kwargs):
|
||||||
|
|
||||||
class DjangoContext(Context):
|
class DjangoContext(Context):
|
||||||
"""
|
"""
|
||||||
This subclass of template.Context automatically populates 'user' and
|
This subclass of template.Context automatically populates itself using
|
||||||
'messages' in the context.
|
the processors defined in TEMPLATE_CONTEXT_PROCESSORS.
|
||||||
|
Additional processors can be specified as a list of callables
|
||||||
|
using the "processors" keyword argument.
|
||||||
"""
|
"""
|
||||||
def __init__(self, request, dict=None):
|
def __init__(self, request, dict=None, processors=None):
|
||||||
Context.__init__(self, dict)
|
Context.__init__(self, dict)
|
||||||
self['user'] = request.user
|
if processors is None:
|
||||||
self['messages'] = request.user.get_and_delete_messages()
|
processors = ()
|
||||||
self['perms'] = PermWrapper(request.user)
|
|
||||||
from django.conf import settings
|
|
||||||
self['LANGUAGES'] = settings.LANGUAGES
|
|
||||||
if hasattr(request, 'LANGUAGE_CODE'):
|
|
||||||
self['LANGUAGE_CODE'] = request.LANGUAGE_CODE
|
|
||||||
else:
|
else:
|
||||||
self['LANGUAGE_CODE'] = settings.LANGUAGE_CODE
|
processors = tuple(processors)
|
||||||
if DEBUG and request.META.get('REMOTE_ADDR') in INTERNAL_IPS:
|
for processor in get_standard_processors() + processors:
|
||||||
self['debug'] = True
|
self.update(processor(request))
|
||||||
from django.core import db
|
|
||||||
self['sql_queries'] = db.db.queries
|
|
||||||
|
|
||||||
# PermWrapper and PermLookupDict proxy the permissions system into objects that
|
# PermWrapper and PermLookupDict proxy the permissions system into objects that
|
||||||
# the template system can understand.
|
# the template system can understand.
|
||||||
|
|
|
@ -3,14 +3,14 @@ from django.core.xheaders import populate_xheaders
|
||||||
from django.core.template import loader
|
from django.core.template import loader
|
||||||
from django.core import formfields, meta
|
from django.core import formfields, meta
|
||||||
from django.views.auth.login import redirect_to_login
|
from django.views.auth.login import redirect_to_login
|
||||||
from django.core.extensions import DjangoContext as Context
|
from django.core.extensions import DjangoContext
|
||||||
from django.core.paginator import ObjectPaginator, InvalidPage
|
from django.core.paginator import ObjectPaginator, InvalidPage
|
||||||
from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect
|
from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect
|
||||||
from django.core.exceptions import Http404, ObjectDoesNotExist, ImproperlyConfigured
|
from django.core.exceptions import Http404, ObjectDoesNotExist, ImproperlyConfigured
|
||||||
|
|
||||||
def create_object(request, app_label, module_name, template_name=None,
|
def create_object(request, app_label, module_name, template_name=None,
|
||||||
template_loader=loader, extra_context={},
|
template_loader=loader, extra_context={}, post_save_redirect=None,
|
||||||
post_save_redirect=None, login_required=False, follow=None):
|
login_required=False, follow=None, context_processors=None):
|
||||||
"""
|
"""
|
||||||
Generic object-creation function.
|
Generic object-creation function.
|
||||||
|
|
||||||
|
@ -60,9 +60,9 @@ def create_object(request, app_label, module_name, template_name=None,
|
||||||
if not template_name:
|
if not template_name:
|
||||||
template_name = "%s/%s_form" % (app_label, module_name)
|
template_name = "%s/%s_form" % (app_label, module_name)
|
||||||
t = template_loader.get_template(template_name)
|
t = template_loader.get_template(template_name)
|
||||||
c = Context(request, {
|
c = DjangoContext(request, {
|
||||||
'form' : form,
|
'form': form,
|
||||||
})
|
}, context_processors)
|
||||||
for key, value in extra_context.items():
|
for key, value in extra_context.items():
|
||||||
if callable(value):
|
if callable(value):
|
||||||
c[key] = value()
|
c[key] = value()
|
||||||
|
@ -71,9 +71,9 @@ def create_object(request, app_label, module_name, template_name=None,
|
||||||
return HttpResponse(t.render(c))
|
return HttpResponse(t.render(c))
|
||||||
|
|
||||||
def update_object(request, app_label, module_name, object_id=None, slug=None,
|
def update_object(request, app_label, module_name, object_id=None, slug=None,
|
||||||
slug_field=None, template_name=None, template_loader=loader,
|
slug_field=None, template_name=None, template_loader=loader,
|
||||||
extra_lookup_kwargs={}, extra_context={}, post_save_redirect=None,
|
extra_lookup_kwargs={}, extra_context={}, post_save_redirect=None,
|
||||||
login_required=False, follow=None):
|
login_required=False, follow=None, context_processors=None):
|
||||||
"""
|
"""
|
||||||
Generic object-update function.
|
Generic object-update function.
|
||||||
|
|
||||||
|
@ -131,10 +131,10 @@ def update_object(request, app_label, module_name, object_id=None, slug=None,
|
||||||
if not template_name:
|
if not template_name:
|
||||||
template_name = "%s/%s_form" % (app_label, module_name)
|
template_name = "%s/%s_form" % (app_label, module_name)
|
||||||
t = template_loader.get_template(template_name)
|
t = template_loader.get_template(template_name)
|
||||||
c = Context(request, {
|
c = DjangoContext(request, {
|
||||||
'form' : form,
|
'form': form,
|
||||||
'object' : object,
|
'object': object,
|
||||||
})
|
}, context_processors)
|
||||||
for key, value in extra_context.items():
|
for key, value in extra_context.items():
|
||||||
if callable(value):
|
if callable(value):
|
||||||
c[key] = value()
|
c[key] = value()
|
||||||
|
@ -145,9 +145,9 @@ def update_object(request, app_label, module_name, object_id=None, slug=None,
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def delete_object(request, app_label, module_name, post_delete_redirect,
|
def delete_object(request, app_label, module_name, post_delete_redirect,
|
||||||
object_id=None, slug=None, slug_field=None, template_name=None,
|
object_id=None, slug=None, slug_field=None, template_name=None,
|
||||||
template_loader=loader, extra_lookup_kwargs={},
|
template_loader=loader, extra_lookup_kwargs={}, extra_context={},
|
||||||
extra_context={}, login_required=False):
|
login_required=False, context_processors=None):
|
||||||
"""
|
"""
|
||||||
Generic object-delete function.
|
Generic object-delete function.
|
||||||
|
|
||||||
|
@ -188,9 +188,9 @@ def delete_object(request, app_label, module_name, post_delete_redirect,
|
||||||
if not template_name:
|
if not template_name:
|
||||||
template_name = "%s/%s_confirm_delete" % (app_label, module_name)
|
template_name = "%s/%s_confirm_delete" % (app_label, module_name)
|
||||||
t = template_loader.get_template(template_name)
|
t = template_loader.get_template(template_name)
|
||||||
c = Context(request, {
|
c = DjangoContext(request, {
|
||||||
'object' : object,
|
'object': object,
|
||||||
})
|
}, context_processors)
|
||||||
for key, value in extra_context.items():
|
for key, value in extra_context.items():
|
||||||
if callable(value):
|
if callable(value):
|
||||||
c[key] = value()
|
c[key] = value()
|
||||||
|
@ -199,4 +199,3 @@ def delete_object(request, app_label, module_name, post_delete_redirect,
|
||||||
response = HttpResponse(t.render(c))
|
response = HttpResponse(t.render(c))
|
||||||
populate_xheaders(request, response, app_label, module_name, getattr(object, object._meta.pk.name))
|
populate_xheaders(request, response, app_label, module_name, getattr(object, object._meta.pk.name))
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
from django.core.template import loader
|
from django.core.template import loader
|
||||||
from django.core.exceptions import Http404, ObjectDoesNotExist
|
from django.core.exceptions import Http404, ObjectDoesNotExist
|
||||||
from django.core.extensions import DjangoContext as Context
|
from django.core.extensions import DjangoContext
|
||||||
from django.core.xheaders import populate_xheaders
|
from django.core.xheaders import populate_xheaders
|
||||||
from django.models import get_module
|
from django.models import get_module
|
||||||
from django.utils.httpwrappers import HttpResponse
|
from django.utils.httpwrappers import HttpResponse
|
||||||
import datetime, time
|
import datetime, time
|
||||||
|
|
||||||
def archive_index(request, app_label, module_name, date_field, num_latest=15,
|
def archive_index(request, app_label, module_name, date_field, num_latest=15,
|
||||||
template_name=None, template_loader=loader,
|
template_name=None, template_loader=loader, extra_lookup_kwargs={},
|
||||||
extra_lookup_kwargs={}, extra_context={}, allow_empty=False):
|
extra_context={}, allow_empty=False, context_processors=None):
|
||||||
"""
|
"""
|
||||||
Generic top-level archive of date-based objects.
|
Generic top-level archive of date-based objects.
|
||||||
|
|
||||||
|
@ -38,10 +38,10 @@ def archive_index(request, app_label, module_name, date_field, num_latest=15,
|
||||||
if not template_name:
|
if not template_name:
|
||||||
template_name = "%s/%s_archive" % (app_label, module_name)
|
template_name = "%s/%s_archive" % (app_label, module_name)
|
||||||
t = template_loader.get_template(template_name)
|
t = template_loader.get_template(template_name)
|
||||||
c = Context(request, {
|
c = DjangoContext(request, {
|
||||||
'date_list' : date_list,
|
'date_list' : date_list,
|
||||||
'latest' : latest,
|
'latest' : latest,
|
||||||
})
|
}, context_processors)
|
||||||
for key, value in extra_context.items():
|
for key, value in extra_context.items():
|
||||||
if callable(value):
|
if callable(value):
|
||||||
c[key] = value()
|
c[key] = value()
|
||||||
|
@ -50,8 +50,8 @@ def archive_index(request, app_label, module_name, date_field, num_latest=15,
|
||||||
return HttpResponse(t.render(c))
|
return HttpResponse(t.render(c))
|
||||||
|
|
||||||
def archive_year(request, year, app_label, module_name, date_field,
|
def archive_year(request, year, app_label, module_name, date_field,
|
||||||
template_name=None, template_loader=loader,
|
template_name=None, template_loader=loader, extra_lookup_kwargs={},
|
||||||
extra_lookup_kwargs={}, extra_context={}):
|
extra_context={}, context_processors=None):
|
||||||
"""
|
"""
|
||||||
Generic yearly archive view.
|
Generic yearly archive view.
|
||||||
|
|
||||||
|
@ -75,10 +75,10 @@ def archive_year(request, year, app_label, module_name, date_field,
|
||||||
if not template_name:
|
if not template_name:
|
||||||
template_name = "%s/%s_archive_year" % (app_label, module_name)
|
template_name = "%s/%s_archive_year" % (app_label, module_name)
|
||||||
t = template_loader.get_template(template_name)
|
t = template_loader.get_template(template_name)
|
||||||
c = Context(request, {
|
c = DjangoContext(request, {
|
||||||
'date_list': date_list,
|
'date_list': date_list,
|
||||||
'year': year,
|
'year': year,
|
||||||
})
|
}, context_processors)
|
||||||
for key, value in extra_context.items():
|
for key, value in extra_context.items():
|
||||||
if callable(value):
|
if callable(value):
|
||||||
c[key] = value()
|
c[key] = value()
|
||||||
|
@ -87,8 +87,8 @@ def archive_year(request, year, app_label, module_name, date_field,
|
||||||
return HttpResponse(t.render(c))
|
return HttpResponse(t.render(c))
|
||||||
|
|
||||||
def archive_month(request, year, month, app_label, module_name, date_field,
|
def archive_month(request, year, month, app_label, module_name, date_field,
|
||||||
month_format='%b', template_name=None, template_loader=loader,
|
month_format='%b', template_name=None, template_loader=loader,
|
||||||
extra_lookup_kwargs={}, extra_context={}):
|
extra_lookup_kwargs={}, extra_context={}, context_processors=None):
|
||||||
"""
|
"""
|
||||||
Generic monthly archive view.
|
Generic monthly archive view.
|
||||||
|
|
||||||
|
@ -123,10 +123,10 @@ def archive_month(request, year, month, app_label, module_name, date_field,
|
||||||
if not template_name:
|
if not template_name:
|
||||||
template_name = "%s/%s_archive_month" % (app_label, module_name)
|
template_name = "%s/%s_archive_month" % (app_label, module_name)
|
||||||
t = template_loader.get_template(template_name)
|
t = template_loader.get_template(template_name)
|
||||||
c = Context(request, {
|
c = DjangoContext(request, {
|
||||||
'object_list': object_list,
|
'object_list': object_list,
|
||||||
'month': date,
|
'month': date,
|
||||||
})
|
}, context_processors)
|
||||||
for key, value in extra_context.items():
|
for key, value in extra_context.items():
|
||||||
if callable(value):
|
if callable(value):
|
||||||
c[key] = value()
|
c[key] = value()
|
||||||
|
@ -135,9 +135,9 @@ def archive_month(request, year, month, app_label, module_name, date_field,
|
||||||
return HttpResponse(t.render(c))
|
return HttpResponse(t.render(c))
|
||||||
|
|
||||||
def archive_day(request, year, month, day, app_label, module_name, date_field,
|
def archive_day(request, year, month, day, app_label, module_name, date_field,
|
||||||
month_format='%b', day_format='%d', template_name=None,
|
month_format='%b', day_format='%d', template_name=None,
|
||||||
template_loader=loader, extra_lookup_kwargs={},
|
template_loader=loader, extra_lookup_kwargs={}, extra_context={},
|
||||||
extra_context={}, allow_empty=False):
|
allow_empty=False, context_processors=None):
|
||||||
"""
|
"""
|
||||||
Generic daily archive view.
|
Generic daily archive view.
|
||||||
|
|
||||||
|
@ -172,12 +172,12 @@ def archive_day(request, year, month, day, app_label, module_name, date_field,
|
||||||
if not template_name:
|
if not template_name:
|
||||||
template_name = "%s/%s_archive_day" % (app_label, module_name)
|
template_name = "%s/%s_archive_day" % (app_label, module_name)
|
||||||
t = template_loader.get_template(template_name)
|
t = template_loader.get_template(template_name)
|
||||||
c = Context(request, {
|
c = DjangoContext(request, {
|
||||||
'object_list': object_list,
|
'object_list': object_list,
|
||||||
'day': date,
|
'day': date,
|
||||||
'previous_day': date - datetime.timedelta(days=1),
|
'previous_day': date - datetime.timedelta(days=1),
|
||||||
'next_day': (date < datetime.date.today()) and (date + datetime.timedelta(days=1)) or None,
|
'next_day': (date < datetime.date.today()) and (date + datetime.timedelta(days=1)) or None,
|
||||||
})
|
}, context_processors)
|
||||||
for key, value in extra_context.items():
|
for key, value in extra_context.items():
|
||||||
if callable(value):
|
if callable(value):
|
||||||
c[key] = value()
|
c[key] = value()
|
||||||
|
@ -198,10 +198,10 @@ def archive_today(request, **kwargs):
|
||||||
return archive_day(request, **kwargs)
|
return archive_day(request, **kwargs)
|
||||||
|
|
||||||
def object_detail(request, year, month, day, app_label, module_name, date_field,
|
def object_detail(request, year, month, day, app_label, module_name, date_field,
|
||||||
month_format='%b', day_format='%d', object_id=None, slug=None,
|
month_format='%b', day_format='%d', object_id=None, slug=None,
|
||||||
slug_field=None, template_name=None, template_name_field=None,
|
slug_field=None, template_name=None, template_name_field=None,
|
||||||
template_loader=loader, extra_lookup_kwargs={},
|
template_loader=loader, extra_lookup_kwargs={}, extra_context={},
|
||||||
extra_context={}):
|
context_processors=None):
|
||||||
"""
|
"""
|
||||||
Generic detail view from year/month/day/slug or year/month/day/id structure.
|
Generic detail view from year/month/day/slug or year/month/day/id structure.
|
||||||
|
|
||||||
|
@ -241,9 +241,9 @@ def object_detail(request, year, month, day, app_label, module_name, date_field,
|
||||||
t = template_loader.select_template(template_name_list)
|
t = template_loader.select_template(template_name_list)
|
||||||
else:
|
else:
|
||||||
t = template_loader.get_template(template_name)
|
t = template_loader.get_template(template_name)
|
||||||
c = Context(request, {
|
c = DjangoContext(request, {
|
||||||
'object': object,
|
'object': object,
|
||||||
})
|
}, context_processors)
|
||||||
for key, value in extra_context.items():
|
for key, value in extra_context.items():
|
||||||
if callable(value):
|
if callable(value):
|
||||||
c[key] = value()
|
c[key] = value()
|
||||||
|
|
|
@ -2,13 +2,13 @@ from django import models
|
||||||
from django.core.template import loader
|
from django.core.template import loader
|
||||||
from django.utils.httpwrappers import HttpResponse
|
from django.utils.httpwrappers import HttpResponse
|
||||||
from django.core.xheaders import populate_xheaders
|
from django.core.xheaders import populate_xheaders
|
||||||
from django.core.extensions import DjangoContext as Context
|
from django.core.extensions import DjangoContext
|
||||||
from django.core.paginator import ObjectPaginator, InvalidPage
|
from django.core.paginator import ObjectPaginator, InvalidPage
|
||||||
from django.core.exceptions import Http404, ObjectDoesNotExist
|
from django.core.exceptions import Http404, ObjectDoesNotExist
|
||||||
|
|
||||||
def object_list(request, app_label, module_name, paginate_by=None, allow_empty=False,
|
def object_list(request, app_label, module_name, paginate_by=None, allow_empty=False,
|
||||||
template_name=None, template_loader=loader,
|
template_name=None, template_loader=loader, extra_lookup_kwargs={},
|
||||||
extra_lookup_kwargs={}, extra_context={}):
|
extra_context={}, context_processors=None):
|
||||||
"""
|
"""
|
||||||
Generic list of objects.
|
Generic list of objects.
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ def object_list(request, app_label, module_name, paginate_by=None, allow_empty=F
|
||||||
else:
|
else:
|
||||||
raise Http404
|
raise Http404
|
||||||
page = int(page)
|
page = int(page)
|
||||||
c = Context(request, {
|
c = DjangoContext(request, {
|
||||||
'object_list': object_list,
|
'object_list': object_list,
|
||||||
'is_paginated': paginator.pages > 1,
|
'is_paginated': paginator.pages > 1,
|
||||||
'results_per_page': paginate_by,
|
'results_per_page': paginate_by,
|
||||||
|
@ -59,13 +59,13 @@ def object_list(request, app_label, module_name, paginate_by=None, allow_empty=F
|
||||||
'previous': page - 1,
|
'previous': page - 1,
|
||||||
'pages': paginator.pages,
|
'pages': paginator.pages,
|
||||||
'hits' : paginator.hits,
|
'hits' : paginator.hits,
|
||||||
})
|
}, context_processors)
|
||||||
else:
|
else:
|
||||||
object_list = mod.get_list(**lookup_kwargs)
|
object_list = mod.get_list(**lookup_kwargs)
|
||||||
c = Context(request, {
|
c = DjangoContext(request, {
|
||||||
'object_list': object_list,
|
'object_list': object_list,
|
||||||
'is_paginated': False
|
'is_paginated': False
|
||||||
})
|
}, context_processors)
|
||||||
if len(object_list) == 0 and not allow_empty:
|
if len(object_list) == 0 and not allow_empty:
|
||||||
raise Http404
|
raise Http404
|
||||||
for key, value in extra_context.items():
|
for key, value in extra_context.items():
|
||||||
|
@ -79,9 +79,9 @@ def object_list(request, app_label, module_name, paginate_by=None, allow_empty=F
|
||||||
return HttpResponse(t.render(c))
|
return HttpResponse(t.render(c))
|
||||||
|
|
||||||
def object_detail(request, app_label, module_name, object_id=None, slug=None,
|
def object_detail(request, app_label, module_name, object_id=None, slug=None,
|
||||||
slug_field=None, template_name=None, template_name_field=None,
|
slug_field=None, template_name=None, template_name_field=None,
|
||||||
template_loader=loader, extra_lookup_kwargs={},
|
template_loader=loader, extra_lookup_kwargs={}, extra_context={},
|
||||||
extra_context={}):
|
context_processors=None):
|
||||||
"""
|
"""
|
||||||
Generic list of objects.
|
Generic list of objects.
|
||||||
|
|
||||||
|
@ -110,9 +110,9 @@ def object_detail(request, app_label, module_name, object_id=None, slug=None,
|
||||||
t = template_loader.select_template(template_name_list)
|
t = template_loader.select_template(template_name_list)
|
||||||
else:
|
else:
|
||||||
t = template_loader.get_template(template_name)
|
t = template_loader.get_template(template_name)
|
||||||
c = Context(request, {
|
c = DjangoContext(request, {
|
||||||
'object': object,
|
'object': object,
|
||||||
})
|
}, context_processors)
|
||||||
for key, value in extra_context.items():
|
for key, value in extra_context.items():
|
||||||
if callable(value):
|
if callable(value):
|
||||||
c[key] = value()
|
c[key] = value()
|
||||||
|
|
|
@ -438,6 +438,15 @@ Authentication data in templates
|
||||||
The currently logged-in user and his/her permissions are made available in the
|
The currently logged-in user and his/her permissions are made available in the
|
||||||
`template context`_ when you use ``DjangoContext``.
|
`template context`_ when you use ``DjangoContext``.
|
||||||
|
|
||||||
|
.. admonition:: Technicality
|
||||||
|
|
||||||
|
Technically, these variables are only made available in the template context
|
||||||
|
if you use ``DjangoContext`` *and* your ``TEMPLATE_CONTEXT_PROCESSORS``
|
||||||
|
setting contains ``"django.core.context_processors.auth"``, which is default.
|
||||||
|
For more, see the `DjangoContext docs`_.
|
||||||
|
|
||||||
|
.. _DjangoContext docs: http://www.djangoproject.com/documentation/templates_python/#subclassing-context-djangocontext
|
||||||
|
|
||||||
Users
|
Users
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@ -454,7 +463,7 @@ Permissions
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
The currently logged-in user's permissions are stored in the template variable
|
The currently logged-in user's permissions are stored in the template variable
|
||||||
``{{ perms }}``. This is an instance of ``django.core.extensions.PermWrapper``,
|
``{{ perms }}``. This is an instance of ``django.core.context_processors.PermWrapper``,
|
||||||
which is a template-friendly proxy of permissions.
|
which is a template-friendly proxy of permissions.
|
||||||
|
|
||||||
In the ``{{ perms }}`` object, single-attribute lookup is a proxy to
|
In the ``{{ perms }}`` object, single-attribute lookup is a proxy to
|
||||||
|
|
|
@ -128,9 +128,14 @@ arguments:
|
||||||
|
|
||||||
``extra_context`` A dictionary of extra data to put into the
|
``extra_context`` A dictionary of extra data to put into the
|
||||||
template's context.
|
template's context.
|
||||||
|
|
||||||
|
``processors`` **New in Django development version.** A tuple of
|
||||||
|
processors to apply to the ``DjangoContext`` of
|
||||||
|
this view's template. See the `DjangoContext docs`_
|
||||||
======================= ==================================================
|
======================= ==================================================
|
||||||
|
|
||||||
.. _`database API docs`: http://www.djangoproject.com/documentation/db_api/
|
.. _database API docs: http://www.djangoproject.com/documentation/db_api/
|
||||||
|
.. _DjangoContext docs: http://www.djangoproject.com/documentation/templates_python/#subclassing-context-djangocontext
|
||||||
|
|
||||||
The date-based generic functions are:
|
The date-based generic functions are:
|
||||||
|
|
||||||
|
@ -247,7 +252,7 @@ The list-detail generic-view framework (in the
|
||||||
except the former simply has two views: a list of objects and an individual
|
except the former simply has two views: a list of objects and an individual
|
||||||
object page.
|
object page.
|
||||||
|
|
||||||
All these views take the same three optional arguments as the date-based ones
|
All these views take the same four optional arguments as the date-based ones
|
||||||
-- and, clearly, they don't accept the ``date_field`` argument.
|
-- and, clearly, they don't accept the ``date_field`` argument.
|
||||||
|
|
||||||
Individual views are:
|
Individual views are:
|
||||||
|
@ -371,4 +376,3 @@ The create/update/delete views are:
|
||||||
|
|
||||||
object
|
object
|
||||||
The object about to be deleted
|
The object about to be deleted
|
||||||
|
|
||||||
|
|
|
@ -547,6 +547,21 @@ The ID, as an integer, of the current site in the ``sites`` database. This is
|
||||||
used so that application data can hook into specific site(s) and a single
|
used so that application data can hook into specific site(s) and a single
|
||||||
database can manage content for multiple sites.
|
database can manage content for multiple sites.
|
||||||
|
|
||||||
|
TEMPLATE_CONTEXT_PROCESSORS
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
Default::
|
||||||
|
|
||||||
|
("django.core.context_processors.auth",
|
||||||
|
"django.core.context_processors.debug",
|
||||||
|
"django.core.context_processors.i18n")
|
||||||
|
|
||||||
|
**Only available in Django development version.**
|
||||||
|
|
||||||
|
A tuple of callables that are used to populate the context in ``DjangoContext``.
|
||||||
|
These callables take a request object as their argument and return a dictionary
|
||||||
|
of items to be merged into the context.
|
||||||
|
|
||||||
TEMPLATE_DEBUG
|
TEMPLATE_DEBUG
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
|
|
@ -240,21 +240,77 @@ Subclassing Context: DjangoContext
|
||||||
|
|
||||||
Django comes with a special ``Context`` class,
|
Django comes with a special ``Context`` class,
|
||||||
``django.core.extensions.DjangoContext``, that acts slightly differently than
|
``django.core.extensions.DjangoContext``, that acts slightly differently than
|
||||||
the normal ``django.core.template.Context``. It takes an ``HttpRequest`` object
|
the normal ``django.core.template.Context``. The first difference is that takes
|
||||||
as its first argument, and it automatically populates the context with a few
|
an `HttpRequest object`_ as its first argument. For example::
|
||||||
variables:
|
|
||||||
|
c = DjangoContext(request, {
|
||||||
|
'foo': 'bar',
|
||||||
|
}
|
||||||
|
|
||||||
|
The second difference is that it automatically populates the context with a few
|
||||||
|
variables, according to your `TEMPLATE_CONTEXT_PROCESSORS setting`_.
|
||||||
|
|
||||||
|
The ``TEMPLATE_CONTEXT_PROCESSORS`` setting is a tuple of callables that take a
|
||||||
|
request object as their argument and return a dictionary of items to be merged
|
||||||
|
into the context. By default, ``TEMPLATE_CONTEXT_PROCESSORS`` is set to::
|
||||||
|
|
||||||
|
("django.core.context_processors.auth",
|
||||||
|
"django.core.context_processors.debug",
|
||||||
|
"django.core.context_processors.i18n")
|
||||||
|
|
||||||
|
Each processor is applied in order. That means, if one processor adds a
|
||||||
|
variable to the context and a second processor adds a variable with the same
|
||||||
|
name, the second will override the first. The default processors are explained
|
||||||
|
below.
|
||||||
|
|
||||||
|
Also, you can give ``DjangoContext`` a list of additional processors, using the
|
||||||
|
optional, third positional argument, ``processors``. In this example, the
|
||||||
|
``DjangoContext`` instance gets a ``ip_address`` variable::
|
||||||
|
|
||||||
|
def ip_address_processor(request):
|
||||||
|
return {'ip_address': request.META['REMOTE_ADDR']}
|
||||||
|
|
||||||
|
def some_view(request):
|
||||||
|
# ...
|
||||||
|
return DjangoContext({
|
||||||
|
'foo': 'bar',
|
||||||
|
}, [ip_address_processor])
|
||||||
|
|
||||||
|
Note: The concept of template-context processors is new in the Django
|
||||||
|
development version. In Django 0.90, ``DjangoContext`` automatically populates
|
||||||
|
the context with all of the values explained below, but it's not possible to
|
||||||
|
add and remove processors.
|
||||||
|
|
||||||
|
Here's what each of the default processors does:
|
||||||
|
|
||||||
|
.. _HttpRequest object: http://www.djangoproject.com/documentation/request_response/#httprequest-objects
|
||||||
|
.. _TEMPLATE_CONTEXT_PROCESSORS setting: http://www.djangoproject.com/documentation/settings/#template-context_processors
|
||||||
|
|
||||||
|
django.core.context_processors.auth
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every
|
||||||
|
``DjangoContext`` will contain these three variables:
|
||||||
|
|
||||||
* ``user`` -- An ``auth.User`` instance representing the currently
|
* ``user`` -- An ``auth.User`` instance representing the currently
|
||||||
logged-in user (or an ``AnonymousUser`` instance, if the client isn't
|
logged-in user (or an ``AnonymousUser`` instance, if the client isn't
|
||||||
logged in). See the `user authentication docs`.
|
logged in). See the `user authentication docs`.
|
||||||
* ``messages`` -- A list of ``auth.Message`` objects for the currently
|
* ``messages`` -- A list of ``auth.Message`` objects for the currently
|
||||||
logged-in user.
|
logged-in user.
|
||||||
* ``perms`` -- An instance of ``django.core.extensions.PermWrapper``,
|
* ``perms`` -- An instance of ``django.core.context_processors.PermWrapper``,
|
||||||
representing the permissions that the currently logged-in user has. See
|
representing the permissions that the currently logged-in user has. See
|
||||||
the `permissions docs`_.
|
the `permissions docs`_.
|
||||||
|
|
||||||
Also, if your ``DEBUG`` setting is set to ``True``, every ``DjangoContext``
|
.. _user authentication docs: http://www.djangoproject.com/documentation/models/authentication/#users
|
||||||
instance has the following two extra variables:
|
.. _permissions docs: http://www.djangoproject.com/documentation/models/authentication/#permissions
|
||||||
|
|
||||||
|
django.core.context_processors.debug
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every
|
||||||
|
``DjangoContext`` will contain these two variables -- but only if your
|
||||||
|
``DEBUG`` setting is set to ``True`` and the request's IP address
|
||||||
|
(``request.META['REMOTE_ADDR']``) is in the ``INTERNAL_IPS`` setting:
|
||||||
|
|
||||||
* ``debug`` -- ``True``. You can use this in templates to test whether
|
* ``debug`` -- ``True``. You can use this in templates to test whether
|
||||||
you're in ``DEBUG`` mode.
|
you're in ``DEBUG`` mode.
|
||||||
|
@ -262,6 +318,25 @@ instance has the following two extra variables:
|
||||||
representing every SQL query that has happened so far during the request
|
representing every SQL query that has happened so far during the request
|
||||||
and how long it took. The list is in order by query.
|
and how long it took. The list is in order by query.
|
||||||
|
|
||||||
|
django.core.context_processors.i18n
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every
|
||||||
|
``DjangoContext`` will contain these two variables:
|
||||||
|
|
||||||
|
* ``LANGUAGES`` -- The value of the `LANGUAGES setting`_.
|
||||||
|
* ``LANGUAGE_CODE`` -- ``request.LANGUAGE_CODE``, if it exists. Otherwise,
|
||||||
|
the value of the `LANGUAGE_CODE setting`_.
|
||||||
|
|
||||||
|
See the `internationalization docs`_ for more.
|
||||||
|
|
||||||
|
.. _LANGUAGES setting: http://www.djangoproject.com/documentation/settings/#languages
|
||||||
|
.. _LANGUAGE_CODE setting: http://www.djangoproject.com/documentation/settings/#language-code
|
||||||
|
.. _internationalization docs: http://www.djangoproject.com/documentation/i18n/
|
||||||
|
|
||||||
|
Subclassing Context: Custom subclasses
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
Feel free to subclass ``Context`` yourself if you find yourself wanting to give
|
Feel free to subclass ``Context`` yourself if you find yourself wanting to give
|
||||||
each template something "automatically." For instance, if you want to give
|
each template something "automatically." For instance, if you want to give
|
||||||
every template automatic access to the current time, use something like this::
|
every template automatic access to the current time, use something like this::
|
||||||
|
@ -281,9 +356,6 @@ This technique has two caveats:
|
||||||
* You'll have to be careful not to set the variable ``current_time`` when
|
* You'll have to be careful not to set the variable ``current_time`` when
|
||||||
you populate this context. If you do, you'll override the other one.
|
you populate this context. If you do, you'll override the other one.
|
||||||
|
|
||||||
.. _user authentication docs: http://www.djangoproject.com/documentation/models/authentication/#users
|
|
||||||
.. _permissions docs: http://www.djangoproject.com/documentation/models/authentication/#permissions
|
|
||||||
|
|
||||||
Loading templates
|
Loading templates
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue