diff --git a/django/template/__init__.py b/django/template/__init__.py
index 5493e5b..03e2a6c 100644
--- a/django/template/__init__.py
+++ b/django/template/__init__.py
@@ -830,9 +830,7 @@ class VariableNode(Node):
             return ''
         return _render_value_in_context(output, context)
 
-def generic_tag_compiler(params, defaults, name, node_class, parser, token):
-    "Returns a template.Node subclass."
-    bits = token.split_contents()[1:]
+def match_number_of_arguments(bits, params, defaults, name):
     bmax = len(params)
     def_len = defaults and len(defaults) or 0
     bmin = bmax - def_len
@@ -842,6 +840,11 @@ def generic_tag_compiler(params, defaults, name, node_class, parser, token):
         else:
             message = "%s takes between %s and %s arguments" % (name, bmin, bmax)
         raise TemplateSyntaxError(message)
+
+def generic_tag_compiler(params, defaults, name, node_class, parser, token):
+    "Returns a template.Node subclass."
+    bits = token.split_contents()[1:]
+    match_number_of_arguments(bits, params, defaults, name)
     return node_class(bits)
 
 class Library(object):
@@ -913,6 +916,38 @@ class Library(object):
         self.tag(getattr(func, "_decorated_function", func).__name__, compile_func)
         return func
 
+    def object_tag(self, func):
+        params, xx, xxx, defaults = getargspec(func)
+
+        class ObjectNode(Node):
+            def __init__(self, vars_to_resolve, var_name):
+                self.vars_to_resolve = map(Variable, vars_to_resolve)
+                self.var_name = var_name
+
+            def render(self, context):
+                resolved_vars = [var.resolve(context) for var in self.vars_to_resolve]
+                obj = func(*resolved_vars)
+                context[self.var_name] = obj
+                return ''
+
+        def object_tag_compiler(params, defaults, name, node_class, parser, token):
+            bits = token.split_contents()[1:]
+
+            if len(bits) < 2 or bits[-2] != 'as':
+                raise TemplateSyntaxError("the next to last argument to %s must be 'as'" % name)
+
+            var_name, bits = bits[-1], bits[:-2]
+            match_number_of_arguments(bits, params, defaults, name)
+
+            return node_class(bits, var_name)
+
+        compile_func = curry(object_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, ObjectNode)
+        compile_func.__doc__ = func.__doc__
+
+        self.tag(getattr(func, "_decorated_function", func).__name__, compile_func)
+
+        return func
+
     def inclusion_tag(self, file_name, context_class=Context, takes_context=False):
         def dec(func):
             params, xx, xxx, defaults = getargspec(func)
diff --git a/docs/howto/custom-template-tags.txt b/docs/howto/custom-template-tags.txt
index c6f7677..6b78711 100644
--- a/docs/howto/custom-template-tags.txt
+++ b/docs/howto/custom-template-tags.txt
@@ -783,6 +783,56 @@ class, like so::
 The difference here is that ``do_current_time()`` grabs the format string and
 the variable name, passing both to ``CurrentTimeNode3``.
 
+Shortcut for loading objects into template variables
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded: 1.2
+
+If you only need to retrieve and store an object in a template variable, it
+might seem cumbersome to write both a renderer and a compilation function
+for such an easy task.
+
+That is why Django provides yet another shortcut -- ``object_tag`` -- which
+makes it easy to write tags that loads objects into template variables.
+
+Its use is very similar to ``simple_tag`` in the way that it takes care of
+all the argument parsing for you, and only requires a single return value --
+the object you'd like to insert into the template variable.
+
+Example::
+
+    def get_latest_polls(max_num):
+        return Poll.objects.order_by('-pub_date')[:max_num]
+
+    register.object_tag(get_latest_polls)
+
+Or if you wish to use the Python 2.4 decorator syntax::
+
+    @register.object_tag
+    def get_latest_polls(max_num):
+        return Poll.objects.order_by('-pub_date')[:max_num]
+
+This tag returns the latest ``Poll``-objects, sorted by descending order, and
+limited by the value of ``max_num``. Its use in a template would look like
+this:
+
+.. code-block:: html+django
+
+    {% get_latest_polls 5 as latest_polls %}
+
+Which would retrieve the 5 latest polls and store them inside a template
+variable named "latest_polls".
+
+Note that the following syntax is *mandatory* for all object_tag's:
+
+.. code-block:: html+django
+
+    {% tag_name [args] as <var_name> %}
+
+Where ``args`` is the arguments for the templatetag ``tag_name``, and
+``var_name`` is the name of the template variable in which the returned object
+should be stored.
+
 Parsing until another block tag
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/tests/regressiontests/templates/object_tag.py b/tests/regressiontests/templates/object_tag.py
new file mode 100644
index 0000000..5f67b9e
--- /dev/null
+++ b/tests/regressiontests/templates/object_tag.py
@@ -0,0 +1,11 @@
+object_tag_tests = """
+>>> t = template.Template('{% load custom %}{% get_meaning_of_life as answer %}{{ answer }}')
+>>> t.render(template.Context())
+u"42"
+>>> t = template.Template('{% load custom %}{% get_mascot_with "awesomeness" "magical powers" as pony %}{{ pony }}')
+>>> t.render(template.Context())
+u"This mascot is filled with awesomeness and magical powers"
+>>> t = template.Template('{% load custom %}{% count "e" word as num %}{{ num }}')
+>>> t.render(template.Context({'word': 'beefcake'}))
+u"3"
+"""
diff --git a/tests/regressiontests/templates/templatetags/custom.py b/tests/regressiontests/templates/templatetags/custom.py
index fdf8d10..bbb8c08 100644
--- a/tests/regressiontests/templates/templatetags/custom.py
+++ b/tests/regressiontests/templates/templatetags/custom.py
@@ -9,3 +9,14 @@ trim = stringfilter(trim)
 
 register.filter(trim)
 
+def get_meaning_of_life():
+    return 42
+register.object_tag(get_meaning_of_life)
+
+def get_mascot_with(power_one, power_two):
+    return 'This mascot is filled with %s and %s' % (power_one, power_two)
+register.object_tag(get_mascot_with)
+
+def count(char, word):
+    return word.count(char)
+register.object_tag(count)
diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
index 9c01b49..0badc86 100644
--- a/tests/regressiontests/templates/tests.py
+++ b/tests/regressiontests/templates/tests.py
@@ -24,6 +24,7 @@ from context import context_tests
 from custom import custom_filters
 from parser import filter_parsing, variable_parsing
 from unicode import unicode_tests
+from object_tag import object_tag_tests
 
 try:
     from loaders import *
@@ -38,6 +39,7 @@ __test__ = {
     'context': context_tests,
     'filter_parsing': filter_parsing,
     'custom_filters': custom_filters,
+    'object_tag': object_tag_tests,
 }
 
 #################################
