Replaced old-style with new-style decorator syntax.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16138 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jannis Leidel 2011-05-01 16:46:02 +00:00
parent da3aa22d04
commit 0b1a061881
24 changed files with 114 additions and 143 deletions

View File

@ -19,6 +19,7 @@ register = Library()
DOT = '.' DOT = '.'
@register.simple_tag
def paginator_number(cl,i): def paginator_number(cl,i):
""" """
Generates an individual page index link in a paginated list. Generates an individual page index link in a paginated list.
@ -29,8 +30,8 @@ def paginator_number(cl,i):
return mark_safe(u'<span class="this-page">%d</span> ' % (i+1)) return mark_safe(u'<span class="this-page">%d</span> ' % (i+1))
else: else:
return mark_safe(u'<a href="%s"%s>%d</a> ' % (escape(cl.get_query_string({PAGE_VAR: i})), (i == cl.paginator.num_pages-1 and ' class="end"' or ''), i+1)) return mark_safe(u'<a href="%s"%s>%d</a> ' % (escape(cl.get_query_string({PAGE_VAR: i})), (i == cl.paginator.num_pages-1 and ' class="end"' or ''), i+1))
paginator_number = register.simple_tag(paginator_number)
@register.inclusion_tag('admin/pagination.html')
def pagination(cl): def pagination(cl):
""" """
Generates the series of links to the pages in a paginated list. Generates the series of links to the pages in a paginated list.
@ -75,7 +76,6 @@ def pagination(cl):
'ALL_VAR': ALL_VAR, 'ALL_VAR': ALL_VAR,
'1': 1, '1': 1,
} }
pagination = register.inclusion_tag('admin/pagination.html')(pagination)
def result_headers(cl): def result_headers(cl):
""" """
@ -123,7 +123,8 @@ def result_headers(cl):
def _boolean_icon(field_val): def _boolean_icon(field_val):
BOOLEAN_MAPPING = {True: 'yes', False: 'no', None: 'unknown'} BOOLEAN_MAPPING = {True: 'yes', False: 'no', None: 'unknown'}
return mark_safe(u'<img src="%simg/admin/icon-%s.gif" alt="%s" />' % (settings.ADMIN_MEDIA_PREFIX, BOOLEAN_MAPPING[field_val], field_val)) return mark_safe(u'<img src="%simg/admin/icon-%s.gif" alt="%s" />' %
(settings.ADMIN_MEDIA_PREFIX, BOOLEAN_MAPPING[field_val], field_val))
def items_for_result(cl, result, form): def items_for_result(cl, result, form):
""" """
@ -222,6 +223,7 @@ def result_hidden_fields(cl):
if form[cl.model._meta.pk.name].is_hidden: if form[cl.model._meta.pk.name].is_hidden:
yield mark_safe(force_unicode(form[cl.model._meta.pk.name])) yield mark_safe(force_unicode(form[cl.model._meta.pk.name]))
@register.inclusion_tag("admin/change_list_results.html")
def result_list(cl): def result_list(cl):
""" """
Displays the headers and data list together Displays the headers and data list together
@ -230,8 +232,8 @@ def result_list(cl):
'result_hidden_fields': list(result_hidden_fields(cl)), 'result_hidden_fields': list(result_hidden_fields(cl)),
'result_headers': list(result_headers(cl)), 'result_headers': list(result_headers(cl)),
'results': list(results(cl))} 'results': list(results(cl))}
result_list = register.inclusion_tag("admin/change_list_results.html")(result_list)
@register.inclusion_tag('admin/date_hierarchy.html')
def date_hierarchy(cl): def date_hierarchy(cl):
""" """
Displays the date hierarchy for date drill-down functionality. Displays the date hierarchy for date drill-down functionality.
@ -303,8 +305,8 @@ def date_hierarchy(cl):
'title': str(year.year), 'title': str(year.year),
} for year in years] } for year in years]
} }
date_hierarchy = register.inclusion_tag('admin/date_hierarchy.html')(date_hierarchy)
@register.inclusion_tag('admin/search_form.html')
def search_form(cl): def search_form(cl):
""" """
Displays a search form for searching the list. Displays a search form for searching the list.
@ -314,12 +316,12 @@ def search_form(cl):
'show_result_count': cl.result_count != cl.full_result_count, 'show_result_count': cl.result_count != cl.full_result_count,
'search_var': SEARCH_VAR 'search_var': SEARCH_VAR
} }
search_form = register.inclusion_tag('admin/search_form.html')(search_form)
@register.inclusion_tag('admin/filter.html')
def admin_list_filter(cl, spec): def admin_list_filter(cl, spec):
return {'title': spec.title(), 'choices' : list(spec.choices(cl))} return {'title': spec.title(), 'choices' : list(spec.choices(cl))}
admin_list_filter = register.inclusion_tag('admin/filter.html')(admin_list_filter)
@register.inclusion_tag('admin/actions.html', takes_context=True)
def admin_actions(context): def admin_actions(context):
""" """
Track the number of times the action field has been rendered on the page, Track the number of times the action field has been rendered on the page,
@ -327,4 +329,3 @@ def admin_actions(context):
""" """
context['action_index'] = context.get('action_index', -1) + 1 context['action_index'] = context.get('action_index', -1) + 1
return context return context
admin_actions = register.inclusion_tag("admin/actions.html", takes_context=True)(admin_actions)

View File

@ -2,6 +2,7 @@ from django import template
register = template.Library() register = template.Library()
@register.inclusion_tag('admin/prepopulated_fields_js.html', takes_context=True)
def prepopulated_fields_js(context): def prepopulated_fields_js(context):
""" """
Creates a list of prepopulated_fields that should render Javascript for Creates a list of prepopulated_fields that should render Javascript for
@ -17,8 +18,8 @@ def prepopulated_fields_js(context):
prepopulated_fields.extend(inline_admin_form.prepopulated_fields) prepopulated_fields.extend(inline_admin_form.prepopulated_fields)
context.update({'prepopulated_fields': prepopulated_fields}) context.update({'prepopulated_fields': prepopulated_fields})
return context return context
prepopulated_fields_js = register.inclusion_tag('admin/prepopulated_fields_js.html', takes_context=True)(prepopulated_fields_js)
@register.inclusion_tag('admin/submit_line.html', takes_context=True)
def submit_row(context): def submit_row(context):
""" """
Displays the row of buttons for delete and save. Displays the row of buttons for delete and save.
@ -39,8 +40,8 @@ def submit_row(context):
'is_popup': is_popup, 'is_popup': is_popup,
'show_save': True 'show_save': True
} }
submit_row = register.inclusion_tag('admin/submit_line.html', takes_context=True)(submit_row)
@register.filter
def cell_count(inline_admin_form): def cell_count(inline_admin_form):
"""Returns the number of cells used in a tabular inline""" """Returns the number of cells used in a tabular inline"""
count = 1 # Hidden cell with hidden 'id' field count = 1 # Hidden cell with hidden 'id' field
@ -53,4 +54,3 @@ def cell_count(inline_admin_form):
# Delete checkbox # Delete checkbox
count += 1 count += 1
return count return count
cell_count = register.filter(cell_count)

View File

@ -20,7 +20,8 @@ class AdminLogNode(template.Node):
context[self.varname] = LogEntry.objects.filter(user__id__exact=user_id).select_related('content_type', 'user')[:self.limit] context[self.varname] = LogEntry.objects.filter(user__id__exact=user_id).select_related('content_type', 'user')[:self.limit]
return '' return ''
class DoGetAdminLog: @register.tag
def get_admin_log(parser, token):
""" """
Populates a template variable with the admin log for the given criteria. Populates a template variable with the admin log for the given criteria.
@ -38,20 +39,18 @@ class DoGetAdminLog:
(user ID) or the name of a template context variable containing the user (user ID) or the name of a template context variable containing the user
object whose ID you want. object whose ID you want.
""" """
def __init__(self, tag_name):
self.tag_name = tag_name
def __call__(self, parser, token):
tokens = token.contents.split() tokens = token.contents.split()
if len(tokens) < 4: if len(tokens) < 4:
raise template.TemplateSyntaxError("'%s' statements require two arguments" % self.tag_name) raise template.TemplateSyntaxError(
"'get_admin_log' statements require two arguments")
if not tokens[1].isdigit(): if not tokens[1].isdigit():
raise template.TemplateSyntaxError("First argument in '%s' must be an integer" % self.tag_name) raise template.TemplateSyntaxError(
"First argument to 'get_admin_log' must be an integer")
if tokens[2] != 'as': if tokens[2] != 'as':
raise template.TemplateSyntaxError("Second argument in '%s' must be 'as'" % self.tag_name) raise template.TemplateSyntaxError(
"Second argument to 'get_admin_log' must be 'as'")
if len(tokens) > 4: if len(tokens) > 4:
if tokens[4] != 'for_user': if tokens[4] != 'for_user':
raise template.TemplateSyntaxError("Fourth argument in '%s' must be 'for_user'" % self.tag_name) raise template.TemplateSyntaxError(
"Fourth argument to 'get_admin_log' must be 'for_user'")
return AdminLogNode(limit=tokens[1], varname=tokens[3], user=(len(tokens) > 5 and tokens[5] or None)) return AdminLogNode(limit=tokens[1], varname=tokens[3], user=(len(tokens) > 5 and tokens[5] or None))
register.tag('get_admin_log', DoGetAdminLog('get_admin_log'))

View File

@ -9,6 +9,7 @@ def staff_member_required(view_func):
Decorator for views that checks that the user is logged in and is a staff Decorator for views that checks that the user is logged in and is a staff
member, displaying the login page if necessary. member, displaying the login page if necessary.
""" """
@wraps(view_func)
def _checklogin(request, *args, **kwargs): def _checklogin(request, *args, **kwargs):
if request.user.is_active and request.user.is_staff: if request.user.is_active and request.user.is_staff:
# The user is valid. Continue to the admin page. # The user is valid. Continue to the admin page.
@ -25,4 +26,4 @@ def staff_member_required(view_func):
}, },
} }
return login(request, **defaults) return login(request, **defaults)
return wraps(view_func)(_checklogin) return _checklogin

View File

@ -27,22 +27,23 @@ def get_root_path():
except urlresolvers.NoReverseMatch: except urlresolvers.NoReverseMatch:
return getattr(settings, "ADMIN_SITE_ROOT_URL", "/admin/") return getattr(settings, "ADMIN_SITE_ROOT_URL", "/admin/")
@staff_member_required
def doc_index(request): def doc_index(request):
if not utils.docutils_is_available: if not utils.docutils_is_available:
return missing_docutils_page(request) return missing_docutils_page(request)
return render_to_response('admin_doc/index.html', { return render_to_response('admin_doc/index.html', {
'root_path': get_root_path(), 'root_path': get_root_path(),
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
doc_index = staff_member_required(doc_index)
@staff_member_required
def bookmarklets(request): def bookmarklets(request):
admin_root = get_root_path() admin_root = get_root_path()
return render_to_response('admin_doc/bookmarklets.html', { return render_to_response('admin_doc/bookmarklets.html', {
'root_path': admin_root, 'root_path': admin_root,
'admin_url': mark_safe("%s://%s%s" % (request.is_secure() and 'https' or 'http', request.get_host(), admin_root)), 'admin_url': mark_safe("%s://%s%s" % (request.is_secure() and 'https' or 'http', request.get_host(), admin_root)),
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
bookmarklets = staff_member_required(bookmarklets)
@staff_member_required
def template_tag_index(request): def template_tag_index(request):
if not utils.docutils_is_available: if not utils.docutils_is_available:
return missing_docutils_page(request) return missing_docutils_page(request)
@ -76,8 +77,8 @@ def template_tag_index(request):
'root_path': get_root_path(), 'root_path': get_root_path(),
'tags': tags 'tags': tags
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
template_tag_index = staff_member_required(template_tag_index)
@staff_member_required
def template_filter_index(request): def template_filter_index(request):
if not utils.docutils_is_available: if not utils.docutils_is_available:
return missing_docutils_page(request) return missing_docutils_page(request)
@ -111,8 +112,8 @@ def template_filter_index(request):
'root_path': get_root_path(), 'root_path': get_root_path(),
'filters': filters 'filters': filters
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
template_filter_index = staff_member_required(template_filter_index)
@staff_member_required
def view_index(request): def view_index(request):
if not utils.docutils_is_available: if not utils.docutils_is_available:
return missing_docutils_page(request) return missing_docutils_page(request)
@ -142,8 +143,8 @@ def view_index(request):
'root_path': get_root_path(), 'root_path': get_root_path(),
'views': views 'views': views
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
view_index = staff_member_required(view_index)
@staff_member_required
def view_detail(request, view): def view_detail(request, view):
if not utils.docutils_is_available: if not utils.docutils_is_available:
return missing_docutils_page(request) return missing_docutils_page(request)
@ -167,8 +168,8 @@ def view_detail(request, view):
'body': body, 'body': body,
'meta': metadata, 'meta': metadata,
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
view_detail = staff_member_required(view_detail)
@staff_member_required
def model_index(request): def model_index(request):
if not utils.docutils_is_available: if not utils.docutils_is_available:
return missing_docutils_page(request) return missing_docutils_page(request)
@ -177,8 +178,8 @@ def model_index(request):
'root_path': get_root_path(), 'root_path': get_root_path(),
'models': m_list 'models': m_list
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
model_index = staff_member_required(model_index)
@staff_member_required
def model_detail(request, app_label, model_name): def model_detail(request, app_label, model_name):
if not utils.docutils_is_available: if not utils.docutils_is_available:
return missing_docutils_page(request) return missing_docutils_page(request)
@ -272,8 +273,8 @@ def model_detail(request, app_label, model_name):
'description': model.__doc__, 'description': model.__doc__,
'fields': fields, 'fields': fields,
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
model_detail = staff_member_required(model_detail)
@staff_member_required
def template_detail(request, template): def template_detail(request, template):
templates = [] templates = []
for site_settings_module in settings.ADMIN_FOR: for site_settings_module in settings.ADMIN_FOR:
@ -297,7 +298,6 @@ def template_detail(request, template):
'name': template, 'name': template,
'templates': templates, 'templates': templates,
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
template_detail = staff_member_required(template_detail)
#################### ####################
# Helper functions # # Helper functions #

View File

@ -14,7 +14,7 @@ class BaseCommentNode(template.Node):
obvious. obvious.
""" """
#@classmethod @classmethod
def handle_token(cls, parser, token): def handle_token(cls, parser, token):
"""Class method to parse get_comment_list/count/form and return a Node.""" """Class method to parse get_comment_list/count/form and return a Node."""
tokens = token.contents.split() tokens = token.contents.split()
@ -43,9 +43,7 @@ class BaseCommentNode(template.Node):
else: else:
raise template.TemplateSyntaxError("%r tag requires 4 or 5 arguments" % tokens[0]) raise template.TemplateSyntaxError("%r tag requires 4 or 5 arguments" % tokens[0])
handle_token = classmethod(handle_token) @staticmethod
#@staticmethod
def lookup_content_type(token, tagname): def lookup_content_type(token, tagname):
try: try:
app, model = token.split('.') app, model = token.split('.')
@ -54,7 +52,6 @@ class BaseCommentNode(template.Node):
raise template.TemplateSyntaxError("Third argument in %r must be in the format 'app.model'" % tagname) raise template.TemplateSyntaxError("Third argument in %r must be in the format 'app.model'" % tagname)
except ContentType.DoesNotExist: except ContentType.DoesNotExist:
raise template.TemplateSyntaxError("%r tag has non-existant content-type: '%s.%s'" % (tagname, app, model)) raise template.TemplateSyntaxError("%r tag has non-existant content-type: '%s.%s'" % (tagname, app, model))
lookup_content_type = staticmethod(lookup_content_type)
def __init__(self, ctype=None, object_pk_expr=None, object_expr=None, as_varname=None, comment=None): def __init__(self, ctype=None, object_pk_expr=None, object_expr=None, as_varname=None, comment=None):
if ctype is None and object_expr is None: if ctype is None and object_expr is None:
@ -146,7 +143,7 @@ class CommentFormNode(BaseCommentNode):
class RenderCommentFormNode(CommentFormNode): class RenderCommentFormNode(CommentFormNode):
"""Render the comment form directly""" """Render the comment form directly"""
#@classmethod @classmethod
def handle_token(cls, parser, token): def handle_token(cls, parser, token):
"""Class method to parse render_comment_form and return a Node.""" """Class method to parse render_comment_form and return a Node."""
tokens = token.contents.split() tokens = token.contents.split()
@ -163,7 +160,6 @@ class RenderCommentFormNode(CommentFormNode):
ctype = BaseCommentNode.lookup_content_type(tokens[2], tokens[0]), ctype = BaseCommentNode.lookup_content_type(tokens[2], tokens[0]),
object_pk_expr = parser.compile_filter(tokens[3]) object_pk_expr = parser.compile_filter(tokens[3])
) )
handle_token = classmethod(handle_token)
def render(self, context): def render(self, context):
ctype, object_pk = self.get_target_ctype_pk(context) ctype, object_pk = self.get_target_ctype_pk(context)
@ -183,7 +179,7 @@ class RenderCommentFormNode(CommentFormNode):
class RenderCommentListNode(CommentListNode): class RenderCommentListNode(CommentListNode):
"""Render the comment list directly""" """Render the comment list directly"""
#@classmethod @classmethod
def handle_token(cls, parser, token): def handle_token(cls, parser, token):
"""Class method to parse render_comment_list and return a Node.""" """Class method to parse render_comment_list and return a Node."""
tokens = token.contents.split() tokens = token.contents.split()
@ -200,7 +196,6 @@ class RenderCommentListNode(CommentListNode):
ctype = BaseCommentNode.lookup_content_type(tokens[2], tokens[0]), ctype = BaseCommentNode.lookup_content_type(tokens[2], tokens[0]),
object_pk_expr = parser.compile_filter(tokens[3]) object_pk_expr = parser.compile_filter(tokens[3])
) )
handle_token = classmethod(handle_token)
def render(self, context): def render(self, context):
ctype, object_pk = self.get_target_ctype_pk(context) ctype, object_pk = self.get_target_ctype_pk(context)
@ -224,7 +219,7 @@ class RenderCommentListNode(CommentListNode):
# the automagic docstrings-into-admin-docs tricks. So each node gets a cute # the automagic docstrings-into-admin-docs tricks. So each node gets a cute
# wrapper function that just exists to hold the docstring. # wrapper function that just exists to hold the docstring.
#@register.tag @register.tag
def get_comment_count(parser, token): def get_comment_count(parser, token):
""" """
Gets the comment count for the given params and populates the template Gets the comment count for the given params and populates the template
@ -245,7 +240,7 @@ def get_comment_count(parser, token):
""" """
return CommentCountNode.handle_token(parser, token) return CommentCountNode.handle_token(parser, token)
#@register.tag @register.tag
def get_comment_list(parser, token): def get_comment_list(parser, token):
""" """
Gets the list of comments for the given params and populates the template Gets the list of comments for the given params and populates the template
@ -267,7 +262,7 @@ def get_comment_list(parser, token):
""" """
return CommentListNode.handle_token(parser, token) return CommentListNode.handle_token(parser, token)
#@register.tag @register.tag
def render_comment_list(parser, token): def render_comment_list(parser, token):
""" """
Render the comment list (as returned by ``{% get_comment_list %}``) Render the comment list (as returned by ``{% get_comment_list %}``)
@ -285,7 +280,7 @@ def render_comment_list(parser, token):
""" """
return RenderCommentListNode.handle_token(parser, token) return RenderCommentListNode.handle_token(parser, token)
#@register.tag @register.tag
def get_comment_form(parser, token): def get_comment_form(parser, token):
""" """
Get a (new) form object to post a new comment. Get a (new) form object to post a new comment.
@ -297,7 +292,7 @@ def get_comment_form(parser, token):
""" """
return CommentFormNode.handle_token(parser, token) return CommentFormNode.handle_token(parser, token)
#@register.tag @register.tag
def render_comment_form(parser, token): def render_comment_form(parser, token):
""" """
Render the comment form (as returned by ``{% render_comment_form %}``) through Render the comment form (as returned by ``{% render_comment_form %}``) through
@ -310,7 +305,7 @@ def render_comment_form(parser, token):
""" """
return RenderCommentFormNode.handle_token(parser, token) return RenderCommentFormNode.handle_token(parser, token)
#@register.simple_tag @register.simple_tag
def comment_form_target(): def comment_form_target():
""" """
Get the target URL for the comment form. Get the target URL for the comment form.
@ -321,7 +316,7 @@ def comment_form_target():
""" """
return comments.get_form_target() return comments.get_form_target()
#@register.simple_tag @register.simple_tag
def get_comment_permalink(comment, anchor_pattern=None): def get_comment_permalink(comment, anchor_pattern=None):
""" """
Get the permalink for a comment, optionally specifying the format of the Get the permalink for a comment, optionally specifying the format of the
@ -335,10 +330,3 @@ def get_comment_permalink(comment, anchor_pattern=None):
return comment.get_absolute_url(anchor_pattern) return comment.get_absolute_url(anchor_pattern)
return comment.get_absolute_url() return comment.get_absolute_url()
register.tag(get_comment_count)
register.tag(get_comment_list)
register.tag(get_comment_form)
register.tag(render_comment_form)
register.simple_tag(comment_form_target)
register.simple_tag(get_comment_permalink)
register.tag(render_comment_list)

View File

@ -339,13 +339,12 @@ class BaseGenericInlineFormSet(BaseModelFormSet):
prefix=prefix prefix=prefix
) )
#@classmethod @classmethod
def get_default_prefix(cls): def get_default_prefix(cls):
opts = cls.model._meta opts = cls.model._meta
return '-'.join((opts.app_label, opts.object_name.lower(), return '-'.join((opts.app_label, opts.object_name.lower(),
cls.ct_field.name, cls.ct_fk_field.name, cls.ct_field.name, cls.ct_fk_field.name,
)) ))
get_default_prefix = classmethod(get_default_prefix)
def save_new(self, form, commit=True): def save_new(self, form, commit=True):
# Avoid a circular import. # Avoid a circular import.

View File

@ -38,6 +38,7 @@ class FlatpageNode(template.Node):
return '' return ''
@register.tag
def get_flatpages(parser, token): def get_flatpages(parser, token):
""" """
Retrieves all flatpage objects available for the current site and Retrieves all flatpage objects available for the current site and
@ -94,5 +95,3 @@ def get_flatpages(parser, token):
return FlatpageNode(context_name, starts_with=prefix, user=user) return FlatpageNode(context_name, starts_with=prefix, user=user)
else: else:
raise template.TemplateSyntaxError(syntax_message) raise template.TemplateSyntaxError(syntax_message)
register.tag('get_flatpages', get_flatpages)

View File

@ -77,6 +77,7 @@ def apnumber(value):
apnumber.is_safe = True apnumber.is_safe = True
register.filter(apnumber) register.filter(apnumber)
@register.filter
def naturalday(value, arg=None): def naturalday(value, arg=None):
""" """
For date values that are tomorrow, today or yesterday compared to For date values that are tomorrow, today or yesterday compared to
@ -101,8 +102,8 @@ def naturalday(value, arg=None):
elif delta.days == -1: elif delta.days == -1:
return _(u'yesterday') return _(u'yesterday')
return defaultfilters.date(value, arg) return defaultfilters.date(value, arg)
register.filter(naturalday)
@register.filter
def naturaltime(value, arg=None): def naturaltime(value, arg=None):
""" """
For date and time values shows how many seconds, minutes or hours ago compared to For date and time values shows how many seconds, minutes or hours ago compared to
@ -133,4 +134,3 @@ def naturaltime(value, arg=None):
elif delta.seconds / 60 / 60 < 24: elif delta.seconds / 60 / 60 < 24:
return _(u'%s hours ago' % (delta.seconds/60/60)) return _(u'%s hours ago' % (delta.seconds/60/60))
return naturalday(value, arg) return naturalday(value, arg)
register.filter(naturaltime)

View File

@ -20,7 +20,7 @@ class LoremNode(template.Node):
paras = ['<p>%s</p>' % p for p in paras] paras = ['<p>%s</p>' % p for p in paras]
return u'\n\n'.join(paras) return u'\n\n'.join(paras)
#@register.tag @register.tag
def lorem(parser, token): def lorem(parser, token):
""" """
Creates random Latin text useful for providing test data in templates. Creates random Latin text useful for providing test data in templates.
@ -64,4 +64,3 @@ def lorem(parser, token):
if len(bits) != 1: if len(bits) != 1:
raise template.TemplateSyntaxError("Incorrect format for %r tag" % tagname) raise template.TemplateSyntaxError("Incorrect format for %r tag" % tagname)
return LoremNode(count, method, common) return LoremNode(count, method, common)
lorem = register.tag(lorem)

View File

@ -218,10 +218,9 @@ class BaseFormSet(StrAndUnicode):
return [self.forms[i[0]] for i in self._ordering] return [self.forms[i[0]] for i in self._ordering]
ordered_forms = property(_get_ordered_forms) ordered_forms = property(_get_ordered_forms)
#@classmethod @classmethod
def get_default_prefix(cls): def get_default_prefix(cls):
return 'form' return 'form'
get_default_prefix = classmethod(get_default_prefix)
def non_form_errors(self): def non_form_errors(self):
""" """

View File

@ -701,11 +701,10 @@ class BaseInlineFormSet(BaseModelFormSet):
setattr(form.instance, self.fk.get_attname(), self.instance.pk) setattr(form.instance, self.fk.get_attname(), self.instance.pk)
return form return form
#@classmethod @classmethod
def get_default_prefix(cls): def get_default_prefix(cls):
from django.db.models.fields.related import RelatedObject from django.db.models.fields.related import RelatedObject
return RelatedObject(cls.fk.rel.to, cls.model, cls.fk).get_accessor_name().replace('+','') return RelatedObject(cls.fk.rel.to, cls.model, cls.fk).get_accessor_name().replace('+','')
get_default_prefix = classmethod(get_default_prefix)
def save_new(self, form, commit=True): def save_new(self, form, commit=True):
# Use commit=False so we can assign the parent key afterwards, then # Use commit=False so we can assign the parent key afterwards, then

View File

@ -823,7 +823,7 @@ class Library(object):
# @register.tag() # @register.tag()
return self.tag_function return self.tag_function
elif name != None and compile_function == None: elif name != None and compile_function == None:
if(callable(name)): if callable(name):
# @register.tag # @register.tag
return self.tag_function(name) return self.tag_function(name)
else: else:
@ -847,7 +847,7 @@ class Library(object):
# @register.filter() # @register.filter()
return self.filter_function return self.filter_function
elif filter_func == None: elif filter_func == None:
if(callable(name)): if callable(name):
# @register.filter # @register.filter
return self.filter_function(name) return self.filter_function(name)
else: else:

View File

@ -501,7 +501,7 @@ class WithNode(Node):
context.pop() context.pop()
return output return output
#@register.tag @register.tag
def autoescape(parser, token): def autoescape(parser, token):
""" """
Force autoescape behaviour for this block. Force autoescape behaviour for this block.
@ -515,18 +515,16 @@ def autoescape(parser, token):
nodelist = parser.parse(('endautoescape',)) nodelist = parser.parse(('endautoescape',))
parser.delete_first_token() parser.delete_first_token()
return AutoEscapeControlNode((arg == 'on'), nodelist) return AutoEscapeControlNode((arg == 'on'), nodelist)
autoescape = register.tag(autoescape)
#@register.tag @register.tag
def comment(parser, token): def comment(parser, token):
""" """
Ignores everything between ``{% comment %}`` and ``{% endcomment %}``. Ignores everything between ``{% comment %}`` and ``{% endcomment %}``.
""" """
parser.skip_past('endcomment') parser.skip_past('endcomment')
return CommentNode() return CommentNode()
comment = register.tag(comment)
#@register.tag @register.tag
def cycle(parser, token): def cycle(parser, token):
""" """
Cycles among the given strings each time this tag is encountered. Cycles among the given strings each time this tag is encountered.
@ -617,12 +615,12 @@ def cycle(parser, token):
values = [parser.compile_filter(arg) for arg in args[1:]] values = [parser.compile_filter(arg) for arg in args[1:]]
node = CycleNode(values) node = CycleNode(values)
return node return node
cycle = register.tag(cycle)
@register.tag
def csrf_token(parser, token): def csrf_token(parser, token):
return CsrfTokenNode() return CsrfTokenNode()
register.tag(csrf_token)
@register.tag
def debug(parser, token): def debug(parser, token):
""" """
Outputs a whole load of debugging information, including the current Outputs a whole load of debugging information, including the current
@ -635,9 +633,8 @@ def debug(parser, token):
</pre> </pre>
""" """
return DebugNode() return DebugNode()
debug = register.tag(debug)
#@register.tag(name="filter") @register.tag('filter')
def do_filter(parser, token): def do_filter(parser, token):
""" """
Filters the contents of the block through variable filters. Filters the contents of the block through variable filters.
@ -659,9 +656,8 @@ def do_filter(parser, token):
nodelist = parser.parse(('endfilter',)) nodelist = parser.parse(('endfilter',))
parser.delete_first_token() parser.delete_first_token()
return FilterNode(filter_expr, nodelist) return FilterNode(filter_expr, nodelist)
do_filter = register.tag("filter", do_filter)
#@register.tag @register.tag
def firstof(parser, token): def firstof(parser, token):
""" """
Outputs the first variable passed that is not False, without escaping. Outputs the first variable passed that is not False, without escaping.
@ -700,9 +696,8 @@ def firstof(parser, token):
if len(bits) < 1: if len(bits) < 1:
raise TemplateSyntaxError("'firstof' statement requires at least one argument") raise TemplateSyntaxError("'firstof' statement requires at least one argument")
return FirstOfNode([parser.compile_filter(bit) for bit in bits]) return FirstOfNode([parser.compile_filter(bit) for bit in bits])
firstof = register.tag(firstof)
#@register.tag(name="for") @register.tag('for')
def do_for(parser, token): def do_for(parser, token):
""" """
Loops over each item in an array. Loops over each item in an array.
@ -792,7 +787,6 @@ def do_for(parser, token):
else: else:
nodelist_empty = None nodelist_empty = None
return ForNode(loopvars, sequence, is_reversed, nodelist_loop, nodelist_empty) return ForNode(loopvars, sequence, is_reversed, nodelist_loop, nodelist_empty)
do_for = register.tag("for", do_for)
def do_ifequal(parser, token, negate): def do_ifequal(parser, token, negate):
bits = list(token.split_contents()) bits = list(token.split_contents())
@ -810,7 +804,7 @@ def do_ifequal(parser, token, negate):
val2 = parser.compile_filter(bits[2]) val2 = parser.compile_filter(bits[2])
return IfEqualNode(val1, val2, nodelist_true, nodelist_false, negate) return IfEqualNode(val1, val2, nodelist_true, nodelist_false, negate)
#@register.tag @register.tag
def ifequal(parser, token): def ifequal(parser, token):
""" """
Outputs the contents of the block if the two arguments equal each other. Outputs the contents of the block if the two arguments equal each other.
@ -828,16 +822,14 @@ def ifequal(parser, token):
{% endifnotequal %} {% endifnotequal %}
""" """
return do_ifequal(parser, token, False) return do_ifequal(parser, token, False)
ifequal = register.tag(ifequal)
#@register.tag @register.tag
def ifnotequal(parser, token): def ifnotequal(parser, token):
""" """
Outputs the contents of the block if the two arguments are not equal. Outputs the contents of the block if the two arguments are not equal.
See ifequal. See ifequal.
""" """
return do_ifequal(parser, token, True) return do_ifequal(parser, token, True)
ifnotequal = register.tag(ifnotequal)
class TemplateLiteral(Literal): class TemplateLiteral(Literal):
def __init__(self, value, text): def __init__(self, value, text):
@ -860,7 +852,7 @@ class TemplateIfParser(IfParser):
def create_var(self, value): def create_var(self, value):
return TemplateLiteral(self.template_parser.compile_filter(value), value) return TemplateLiteral(self.template_parser.compile_filter(value), value)
#@register.tag(name="if") @register.tag('if')
def do_if(parser, token): def do_if(parser, token):
""" """
The ``{% if %}`` tag evaluates a variable, and if that variable is "true" The ``{% if %}`` tag evaluates a variable, and if that variable is "true"
@ -927,9 +919,8 @@ def do_if(parser, token):
else: else:
nodelist_false = NodeList() nodelist_false = NodeList()
return IfNode(var, nodelist_true, nodelist_false) return IfNode(var, nodelist_true, nodelist_false)
do_if = register.tag("if", do_if)
#@register.tag @register.tag
def ifchanged(parser, token): def ifchanged(parser, token):
""" """
Checks if a value has changed from the last iteration of a loop. Checks if a value has changed from the last iteration of a loop.
@ -968,9 +959,8 @@ def ifchanged(parser, token):
nodelist_false = NodeList() nodelist_false = NodeList()
values = [parser.compile_filter(bit) for bit in bits[1:]] values = [parser.compile_filter(bit) for bit in bits[1:]]
return IfChangedNode(nodelist_true, nodelist_false, *values) return IfChangedNode(nodelist_true, nodelist_false, *values)
ifchanged = register.tag(ifchanged)
#@register.tag @register.tag
def ssi(parser, token): def ssi(parser, token):
""" """
Outputs the contents of a given file into the page. Outputs the contents of a given file into the page.
@ -1003,9 +993,8 @@ def ssi(parser, token):
raise TemplateSyntaxError("Second (optional) argument to %s tag" raise TemplateSyntaxError("Second (optional) argument to %s tag"
" must be 'parsed'" % bits[0]) " must be 'parsed'" % bits[0])
return SsiNode(bits[1], parsed, legacy_filepath=True) return SsiNode(bits[1], parsed, legacy_filepath=True)
ssi = register.tag(ssi)
#@register.tag @register.tag
def load(parser, token): def load(parser, token):
""" """
Loads a custom template tag set. Loads a custom template tag set.
@ -1053,9 +1042,8 @@ def load(parser, token):
raise TemplateSyntaxError("'%s' is not a valid tag library: %s" % raise TemplateSyntaxError("'%s' is not a valid tag library: %s" %
(taglib, e)) (taglib, e))
return LoadNode() return LoadNode()
load = register.tag(load)
#@register.tag @register.tag
def now(parser, token): def now(parser, token):
""" """
Displays the date, formatted according to the given string. Displays the date, formatted according to the given string.
@ -1072,9 +1060,8 @@ def now(parser, token):
raise TemplateSyntaxError("'now' statement takes one argument") raise TemplateSyntaxError("'now' statement takes one argument")
format_string = bits[1] format_string = bits[1]
return NowNode(format_string) return NowNode(format_string)
now = register.tag(now)
#@register.tag @register.tag
def regroup(parser, token): def regroup(parser, token):
""" """
Regroups a list of alike objects by a common attribute. Regroups a list of alike objects by a common attribute.
@ -1136,8 +1123,8 @@ def regroup(parser, token):
var_name = lastbits_reversed[0][::-1] var_name = lastbits_reversed[0][::-1]
return RegroupNode(target, expression, var_name) return RegroupNode(target, expression, var_name)
regroup = register.tag(regroup)
@register.tag
def spaceless(parser, token): def spaceless(parser, token):
""" """
Removes whitespace between HTML tags, including tab and newline characters. Removes whitespace between HTML tags, including tab and newline characters.
@ -1166,9 +1153,8 @@ def spaceless(parser, token):
nodelist = parser.parse(('endspaceless',)) nodelist = parser.parse(('endspaceless',))
parser.delete_first_token() parser.delete_first_token()
return SpacelessNode(nodelist) return SpacelessNode(nodelist)
spaceless = register.tag(spaceless)
#@register.tag @register.tag
def templatetag(parser, token): def templatetag(parser, token):
""" """
Outputs one of the bits used to compose template tags. Outputs one of the bits used to compose template tags.
@ -1200,8 +1186,8 @@ def templatetag(parser, token):
" Must be one of: %s" % " Must be one of: %s" %
(tag, TemplateTagNode.mapping.keys())) (tag, TemplateTagNode.mapping.keys()))
return TemplateTagNode(tag) return TemplateTagNode(tag)
templatetag = register.tag(templatetag)
@register.tag
def url(parser, token): def url(parser, token):
""" """
Returns an absolute URL matching given view with its parameters. Returns an absolute URL matching given view with its parameters.
@ -1299,9 +1285,8 @@ def url(parser, token):
args.append(parser.compile_filter(value)) args.append(parser.compile_filter(value))
return URLNode(viewname, args, kwargs, asvar, legacy_view_name=True) return URLNode(viewname, args, kwargs, asvar, legacy_view_name=True)
url = register.tag(url)
#@register.tag @register.tag
def widthratio(parser, token): def widthratio(parser, token):
""" """
For creating bar charts and such, this tag calculates the ratio of a given For creating bar charts and such, this tag calculates the ratio of a given
@ -1323,9 +1308,8 @@ def widthratio(parser, token):
return WidthRatioNode(parser.compile_filter(this_value_expr), return WidthRatioNode(parser.compile_filter(this_value_expr),
parser.compile_filter(max_value_expr), parser.compile_filter(max_value_expr),
parser.compile_filter(max_width)) parser.compile_filter(max_width))
widthratio = register.tag(widthratio)
#@register.tag @register.tag('with')
def do_with(parser, token): def do_with(parser, token):
""" """
Adds one or more values to the context (inside of this block) for caching Adds one or more values to the context (inside of this block) for caching
@ -1358,4 +1342,3 @@ def do_with(parser, token):
nodelist = parser.parse(('endwith',)) nodelist = parser.parse(('endwith',))
parser.delete_first_token() parser.delete_first_token()
return WithNode(None, None, nodelist, extra_context=extra_context) return WithNode(None, None, nodelist, extra_context=extra_context)
do_with = register.tag('with', do_with)

View File

@ -173,6 +173,7 @@ class IncludeNode(BaseIncludeNode):
raise raise
return '' return ''
@register.tag('block')
def do_block(parser, token): def do_block(parser, token):
""" """
Define a block that can be overridden by child templates. Define a block that can be overridden by child templates.
@ -193,6 +194,7 @@ def do_block(parser, token):
parser.delete_first_token() parser.delete_first_token()
return BlockNode(block_name, nodelist) return BlockNode(block_name, nodelist)
@register.tag('extends')
def do_extends(parser, token): def do_extends(parser, token):
""" """
Signal that this template extends a parent template. Signal that this template extends a parent template.
@ -216,6 +218,7 @@ def do_extends(parser, token):
raise TemplateSyntaxError("'%s' cannot appear more than once in the same template" % bits[0]) raise TemplateSyntaxError("'%s' cannot appear more than once in the same template" % bits[0])
return ExtendsNode(nodelist, parent_name, parent_name_expr) return ExtendsNode(nodelist, parent_name, parent_name_expr)
@register.tag('include')
def do_include(parser, token): def do_include(parser, token):
""" """
Loads a template and renders it with the current context. You can pass Loads a template and renders it with the current context. You can pass
@ -261,7 +264,3 @@ def do_include(parser, token):
isolated_context=isolated_context) isolated_context=isolated_context)
return IncludeNode(parser.compile_filter(bits[1]), extra_context=namemap, return IncludeNode(parser.compile_filter(bits[1]), extra_context=namemap,
isolated_context=isolated_context) isolated_context=isolated_context)
register.tag('block', do_block)
register.tag('extends', do_extends)
register.tag('include', do_include)

View File

@ -32,6 +32,7 @@ class CacheNode(Node):
cache.set(cache_key, value, expire_time) cache.set(cache_key, value, expire_time)
return value return value
@register.tag('cache')
def do_cache(parser, token): def do_cache(parser, token):
""" """
This will cache the contents of a template fragment for a given amount This will cache the contents of a template fragment for a given amount
@ -59,5 +60,3 @@ def do_cache(parser, token):
if len(tokens) < 3: if len(tokens) < 3:
raise TemplateSyntaxError(u"'%r' tag requires at least 2 arguments." % tokens[0]) raise TemplateSyntaxError(u"'%r' tag requires at least 2 arguments." % tokens[0])
return CacheNode(nodelist, tokens[1], tokens[2], tokens[3:]) return CacheNode(nodelist, tokens[1], tokens[2], tokens[3:])
register.tag('cache', do_cache)

View File

@ -117,6 +117,7 @@ class BlockTranslateNode(Node):
context.pop() context.pop()
return result % data return result % data
@register.tag("get_available_languages")
def do_get_available_languages(parser, token): def do_get_available_languages(parser, token):
""" """
This will store a list of available languages This will store a list of available languages
@ -138,6 +139,7 @@ def do_get_available_languages(parser, token):
raise TemplateSyntaxError("'get_available_languages' requires 'as variable' (got %r)" % args) raise TemplateSyntaxError("'get_available_languages' requires 'as variable' (got %r)" % args)
return GetAvailableLanguagesNode(args[2]) return GetAvailableLanguagesNode(args[2])
@register.tag("get_language_info")
def do_get_language_info(parser, token): def do_get_language_info(parser, token):
""" """
This will store the language information dictionary for the given language This will store the language information dictionary for the given language
@ -156,6 +158,7 @@ def do_get_language_info(parser, token):
raise TemplateSyntaxError("'%s' requires 'for string as variable' (got %r)" % (args[0], args[1:])) raise TemplateSyntaxError("'%s' requires 'for string as variable' (got %r)" % (args[0], args[1:]))
return GetLanguageInfoNode(args[2], args[4]) return GetLanguageInfoNode(args[2], args[4])
@register.tag("get_language_info_list")
def do_get_language_info_list(parser, token): def do_get_language_info_list(parser, token):
""" """
This will store a list of language information dictionaries for the given This will store a list of language information dictionaries for the given
@ -178,15 +181,19 @@ def do_get_language_info_list(parser, token):
raise TemplateSyntaxError("'%s' requires 'for sequence as variable' (got %r)" % (args[0], args[1:])) raise TemplateSyntaxError("'%s' requires 'for sequence as variable' (got %r)" % (args[0], args[1:]))
return GetLanguageInfoListNode(args[2], args[4]) return GetLanguageInfoListNode(args[2], args[4])
@register.filter
def language_name(lang_code): def language_name(lang_code):
return translation.get_language_info(lang_code)['name'] return translation.get_language_info(lang_code)['name']
@register.filter
def language_name_local(lang_code): def language_name_local(lang_code):
return translation.get_language_info(lang_code)['name_local'] return translation.get_language_info(lang_code)['name_local']
@register.filter
def language_bidi(lang_code): def language_bidi(lang_code):
return translation.get_language_info(lang_code)['bidi'] return translation.get_language_info(lang_code)['bidi']
@register.tag("get_current_language")
def do_get_current_language(parser, token): def do_get_current_language(parser, token):
""" """
This will store the current language in the context. This will store the current language in the context.
@ -204,6 +211,7 @@ def do_get_current_language(parser, token):
raise TemplateSyntaxError("'get_current_language' requires 'as variable' (got %r)" % args) raise TemplateSyntaxError("'get_current_language' requires 'as variable' (got %r)" % args)
return GetCurrentLanguageNode(args[2]) return GetCurrentLanguageNode(args[2])
@register.tag("get_current_language_bidi")
def do_get_current_language_bidi(parser, token): def do_get_current_language_bidi(parser, token):
""" """
This will store the current language layout in the context. This will store the current language layout in the context.
@ -221,6 +229,7 @@ def do_get_current_language_bidi(parser, token):
raise TemplateSyntaxError("'get_current_language_bidi' requires 'as variable' (got %r)" % args) raise TemplateSyntaxError("'get_current_language_bidi' requires 'as variable' (got %r)" % args)
return GetCurrentLanguageBidiNode(args[2]) return GetCurrentLanguageBidiNode(args[2])
@register.tag("trans")
def do_translate(parser, token): def do_translate(parser, token):
""" """
This will mark a string for translation and will This will mark a string for translation and will
@ -279,6 +288,7 @@ def do_translate(parser, token):
value, noop = TranslateParser(token.contents).top() value, noop = TranslateParser(token.contents).top()
return TranslateNode(parser.compile_filter(value), noop) return TranslateNode(parser.compile_filter(value), noop)
@register.tag("blocktrans")
def do_block_translate(parser, token): def do_block_translate(parser, token):
""" """
This will translate a block of text with parameters. This will translate a block of text with parameters.
@ -356,15 +366,3 @@ def do_block_translate(parser, token):
return BlockTranslateNode(extra_context, singular, plural, countervar, return BlockTranslateNode(extra_context, singular, plural, countervar,
counter) counter)
register.tag('get_available_languages', do_get_available_languages)
register.tag('get_language_info', do_get_language_info)
register.tag('get_language_info_list', do_get_language_info_list)
register.tag('get_current_language', do_get_current_language)
register.tag('get_current_language_bidi', do_get_current_language_bidi)
register.tag('trans', do_translate)
register.tag('blocktrans', do_block_translate)
register.filter(language_name)
register.filter(language_name_local)
register.filter(language_bidi)

View File

@ -77,6 +77,7 @@ def make_middleware_decorator(middleware_class):
def _make_decorator(*m_args, **m_kwargs): def _make_decorator(*m_args, **m_kwargs):
middleware = middleware_class(*m_args, **m_kwargs) middleware = middleware_class(*m_args, **m_kwargs)
def _decorator(view_func): def _decorator(view_func):
@wraps(view_func, assigned=available_attrs(view_func))
def _wrapped_view(request, *args, **kwargs): def _wrapped_view(request, *args, **kwargs):
if hasattr(middleware, 'process_request'): if hasattr(middleware, 'process_request'):
result = middleware.process_request(request) result = middleware.process_request(request)
@ -99,6 +100,6 @@ def make_middleware_decorator(middleware_class):
if result is not None: if result is not None:
return result return result
return response return response
return wraps(view_func, assigned=available_attrs(view_func))(_wrapped_view) return _wrapped_view
return _decorator return _decorator
return _make_decorator return _make_decorator

View File

@ -17,6 +17,7 @@ def memoize(func, cache, num_args):
Only the first num_args are considered when creating the key. Only the first num_args are considered when creating the key.
""" """
@wraps(func)
def wrapper(*args): def wrapper(*args):
mem_args = args[:num_args] mem_args = args[:num_args]
if mem_args in cache: if mem_args in cache:
@ -24,7 +25,7 @@ def memoize(func, cache, num_args):
result = func(*args) result = func(*args)
cache[mem_args] = result cache[mem_args] = result
return result return result
return wraps(func)(wrapper) return wrapper
class Promise(object): class Promise(object):
""" """
@ -135,11 +136,12 @@ def lazy(func, *resultclasses):
memo[id(self)] = self memo[id(self)] = self
return self return self
@wraps(func)
def __wrapper__(*args, **kw): def __wrapper__(*args, **kw):
# Creates the proxy object, instead of the actual value. # Creates the proxy object, instead of the actual value.
return __proxy__(args, kw) return __proxy__(args, kw)
return wraps(func)(__wrapper__) return __wrapper__
def _lazy_proxy_unpickle(func, args, kwargs, *resultclasses): def _lazy_proxy_unpickle(func, args, kwargs, *resultclasses):
return lazy(func, *resultclasses)(*args, **kwargs) return lazy(func, *resultclasses)(*args, **kwargs)
@ -151,6 +153,7 @@ def allow_lazy(func, *resultclasses):
immediately, otherwise a __proxy__ is returned that will evaluate the immediately, otherwise a __proxy__ is returned that will evaluate the
function when needed. function when needed.
""" """
@wraps(func)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
for arg in list(args) + kwargs.values(): for arg in list(args) + kwargs.values():
if isinstance(arg, Promise): if isinstance(arg, Promise):
@ -158,7 +161,7 @@ def allow_lazy(func, *resultclasses):
else: else:
return func(*args, **kwargs) return func(*args, **kwargs)
return lazy(func, *resultclasses)(*args, **kwargs) return lazy(func, *resultclasses)(*args, **kwargs)
return wraps(func)(wrapper) return wrapper
class LazyObject(object): class LazyObject(object):
""" """

View File

@ -58,11 +58,12 @@ def cache_page(*args, **kwargs):
def cache_control(**kwargs): def cache_control(**kwargs):
def _cache_controller(viewfunc): def _cache_controller(viewfunc):
@wraps(viewfunc, assigned=available_attrs(viewfunc))
def _cache_controlled(request, *args, **kw): def _cache_controlled(request, *args, **kw):
response = viewfunc(request, *args, **kw) response = viewfunc(request, *args, **kw)
patch_cache_control(response, **kwargs) patch_cache_control(response, **kwargs)
return response return response
return wraps(viewfunc, assigned=available_attrs(viewfunc))(_cache_controlled) return _cache_controlled
return _cache_controller return _cache_controller
@ -71,8 +72,9 @@ def never_cache(view_func):
Decorator that adds headers to a response so that it will Decorator that adds headers to a response so that it will
never be cached. never be cached.
""" """
@wraps(view_func, assigned=available_attrs(view_func))
def _wrapped_view_func(request, *args, **kwargs): def _wrapped_view_func(request, *args, **kwargs):
response = view_func(request, *args, **kwargs) response = view_func(request, *args, **kwargs)
add_never_cache_headers(response) add_never_cache_headers(response)
return response return response
return wraps(view_func, assigned=available_attrs(view_func))(_wrapped_view_func) return _wrapped_view_func

View File

@ -29,6 +29,7 @@ def require_http_methods(request_method_list):
Note that request methods should be in uppercase. Note that request methods should be in uppercase.
""" """
def decorator(func): def decorator(func):
@wraps(func, assigned=available_attrs(func))
def inner(request, *args, **kwargs): def inner(request, *args, **kwargs):
if request.method not in request_method_list: if request.method not in request_method_list:
logger.warning('Method Not Allowed (%s): %s' % (request.method, request.path), logger.warning('Method Not Allowed (%s): %s' % (request.method, request.path),
@ -39,7 +40,7 @@ def require_http_methods(request_method_list):
) )
return HttpResponseNotAllowed(request_method_list) return HttpResponseNotAllowed(request_method_list)
return func(request, *args, **kwargs) return func(request, *args, **kwargs)
return wraps(func, assigned=available_attrs(func))(inner) return inner
return decorator return decorator
require_GET = require_http_methods(["GET"]) require_GET = require_http_methods(["GET"])

View File

@ -14,11 +14,12 @@ def vary_on_headers(*headers):
Note that the header names are not case-sensitive. Note that the header names are not case-sensitive.
""" """
def decorator(func): def decorator(func):
@wraps(func, assigned=available_attrs(func))
def inner_func(*args, **kwargs): def inner_func(*args, **kwargs):
response = func(*args, **kwargs) response = func(*args, **kwargs)
patch_vary_headers(response, headers) patch_vary_headers(response, headers)
return response return response
return wraps(func, assigned=available_attrs(func))(inner_func) return inner_func
return decorator return decorator
def vary_on_cookie(func): def vary_on_cookie(func):
@ -30,8 +31,9 @@ def vary_on_cookie(func):
def index(request): def index(request):
... ...
""" """
@wraps(func, assigned=available_attrs(func))
def inner_func(*args, **kwargs): def inner_func(*args, **kwargs):
response = func(*args, **kwargs) response = func(*args, **kwargs)
patch_vary_headers(response, ('Cookie',)) patch_vary_headers(response, ('Cookie',))
return response return response
return wraps(func, assigned=available_attrs(func))(inner_func) return inner_func

View File

@ -6,7 +6,6 @@ from django.db import transaction, connection
from django.db.utils import ConnectionHandler, DEFAULT_DB_ALIAS, DatabaseError from django.db.utils import ConnectionHandler, DEFAULT_DB_ALIAS, DatabaseError
from django.test import (TransactionTestCase, skipIfDBFeature, from django.test import (TransactionTestCase, skipIfDBFeature,
skipUnlessDBFeature) skipUnlessDBFeature)
from django.utils.functional import wraps
from django.utils import unittest from django.utils import unittest
from models import Person from models import Person

View File

@ -1,6 +1,6 @@
from django.contrib.admin.views.decorators import staff_member_required from django.contrib.admin.views.decorators import staff_member_required
from django.http import HttpResponse from django.http import HttpResponse
@staff_member_required
def secure_view(request): def secure_view(request):
return HttpResponse('%s' % request.POST) return HttpResponse('%s' % request.POST)
secure_view = staff_member_required(secure_view)