Index: django/contrib/admin/views/stages/add.py
===================================================================
--- django/contrib/admin/views/stages/add.py	(revision 1817)
+++ django/contrib/admin/views/stages/add.py	(working copy)
@@ -4,6 +4,7 @@
 from django.contrib.admin.views.stages.modify import render_change_form
 from django.core import formfields, template
 from django.core.extensions import DjangoContext as Context
+from django.core.extensions import ManipulatorContext
 from django.db import models
 from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect
 from django.utils.text import capfirst, get_text_list
@@ -22,7 +23,8 @@
 
     if not request.user.has_perm(app_label + '.' + opts.get_add_permission()):
         raise PermissionDenied
-    manipulator = model.AddManipulator()
+    context = ManipulatorContext(model, request)
+    manipulator = model.AddManipulator(context=context)
     if request.POST:
         new_data = request.POST.copy()
         if opts.has_field_type(models.FileField):
Index: django/contrib/admin/views/stages/change.py
===================================================================
--- django/contrib/admin/views/stages/change.py	(revision 1817)
+++ django/contrib/admin/views/stages/change.py	(working copy)
@@ -1,6 +1,7 @@
 from django.contrib.admin.views.main import get_model_and_app
 from django.core import formfields, template
 from django.core.extensions import DjangoContext as Context
+from django.core.extensions import ManipulatorContext
 from django.contrib.admin.views.stages.modify import render_change_form
 from django.db import models
 from django.utils.text import capfirst, get_text_list
@@ -36,9 +37,10 @@
         raise PermissionDenied
     if request.POST and request.POST.has_key("_saveasnew"):
         return add_stage(request, path, form_url='../../add/')
+    context = ManipulatorContext(model, request)
     
     try:
-        manipulator = model.ChangeManipulator(object_id)
+        manipulator = model.ChangeManipulator(object_id, context=context)
     except ObjectDoesNotExist:
         raise Http404
 
Index: django/db/models/manipulators.py
===================================================================
--- django/db/models/manipulators.py	(revision 1817)
+++ django/db/models/manipulators.py	(working copy)
@@ -62,6 +62,9 @@
 
     name = property(_get_name)
 
+# TODO: I don't like initializing the manipulator with the context, but it's
+# easier than passing around the context to a bunch of different methods in
+# the manipulator        
 class AutomaticManipulator(Manipulator, Naming):
     def _prepare(cls, model):
         cls.model = model
@@ -82,7 +85,7 @@
         setattr(other_cls, name, ManipulatorDescriptor(name, cls))
     contribute_to_class = classmethod(contribute_to_class)
 
-    def __init__(self, original_object=None, follow=None, name_parts=() ):
+    def __init__(self, original_object=None, follow=None, name_parts=(), context=None):
         Naming.__init__(self, name_parts)
         if name_parts == ():
             self.follow = self.model._meta.get_follow(follow)
@@ -90,9 +93,10 @@
             self.follow = follow
         self.fields_, self.children = [], {}
         self.original_object = original_object
+        self.context = context
         for f in self.opts.get_data_holders(self.follow):
             fol = self.follow[f.name]
-            fields,manipulators = f.get_fields_and_manipulators(self.opts, self, follow=fol)
+            fields,manipulators = f.get_fields_and_manipulators(self.opts, self, follow=fol, context=self.context)
 
             if fields != None:
                 self.fields_.extend(fields)
@@ -145,7 +149,7 @@
                 # Fields with auto_now_add should keep their original value in the change stage.
                 auto_now_add = self.change and getattr(f, 'auto_now_add', False)
                 if self.follow.get(f.name, None) and not auto_now_add:
-                    param = f.get_manipulator_new_data(expanded_data)
+                    param = f.get_manipulator_new_data(expanded_data, context=self.context)
                 else:
                     param = self.get_original_value(f)
             params[f.attname] = param
@@ -280,8 +284,8 @@
 class ModelAddManipulator(AutomaticManipulator):
     change = False
     add = True
-    def __init__(self, follow=None, name_parts=()):
-        super(ModelAddManipulator, self).__init__(follow=follow, name_parts=name_parts)
+    def __init__(self, follow=None, name_parts=(), context=None):
+        super(ModelAddManipulator, self).__init__(follow=follow, name_parts=name_parts, context=context)
 
     def get_original_value(self, field):
         return field.get_default()
@@ -293,7 +297,7 @@
     change = True
     add = False
 
-    def __init__(self, obj_key=None, follow=None, name_parts=()):
+    def __init__(self, obj_key=None, follow=None, name_parts=(), context=None):
         assert obj_key is not None, "ChangeManipulator.__init__() must be passed obj_key parameter."
         opts = self.model._meta
         if isinstance(obj_key, self.model):
@@ -321,7 +325,7 @@
                 else:
                     raise
 
-        super(ModelChangeManipulator, self).__init__(original_object=original_object, follow=follow, name_parts=name_parts)
+        super(ModelChangeManipulator, self).__init__(original_object=original_object, follow=follow, name_parts=name_parts, context=context)
         #self.original_object = original_object
 
         #if self.opts.get_ordered_objects():
@@ -336,10 +340,11 @@
         return "<Automatic ChangeManipulator '%s' for %s:%r >" % (self.name_prefix, self.model.__name__, self.obj_key)
 
 class ManipulatorCollection(list, Naming):
-    def __init__(self, model, follow, name_parts=()):
+    def __init__(self, model, follow, name_parts=(), context=None):
         Naming.__init__(self, name_parts)
         self.model = model
         self.follow = follow
+        self.context = context
         self._load()
 
     def _get_list(self):
@@ -349,7 +354,7 @@
         man_class = self.model.ChangeManipulator
 
         for i,obj in enumerate(self._get_list()):
-            self.append(man_class(obj,self.follow, self.name_parts + (str(i),)  ))
+            self.append(man_class(obj, self.follow, self.name_parts + (str(i),), context=self.context))
 
     def _save_child(self, manip, parent_key):
         manip.save_from_update()
@@ -438,7 +443,7 @@
             self.append(None)
 
         prefix = '%s%s.' % (self.name_prefix, index )
-        child_manip = man_class(self.follow, self.name_parts + ( str(index), )  )
+        child_manip = man_class(self.follow, self.name_parts + (str(index),), context=self.context)
 
         self[index] = child_manip
         return child_manip
Index: django/db/models/fields/__init__.py
===================================================================
--- django/db/models/fields/__init__.py	(revision 1817)
+++ django/db/models/fields/__init__.py	(working copy)
@@ -218,7 +218,7 @@
             field_objs = self.get_manipulator_field_objs()
         return (field_objs,params)
 
-    def get_fields_and_manipulators(self, opts, manipulator, follow ):
+    def get_fields_and_manipulators(self, opts, manipulator, follow, context=None):
         change = manipulator.change
         rel = manipulator.name_prefix != ''
         name_prefix = manipulator.name_prefix
@@ -278,7 +278,7 @@
     def get_validator_unique_lookup_type(self):
         return '%s__exact' % f.name
 
-    def get_manipulator_new_data(self, new_data, rel=False):
+    def get_manipulator_new_data(self, new_data, rel=False, context=None):
         """
         Given the full new_data dictionary (from the manipulator), returns this
         field's data.
@@ -329,6 +329,9 @@
     def bind(self, fieldmapping, original, bound_field_class=BoundField):
         return bound_field_class(self, fieldmapping, original)
 
+    def get_context_processors(self):
+        return []
+
 class AutoField(Field):
     empty_strings_allowed = False
     def __init__(self, *args, **kwargs):
@@ -343,13 +346,13 @@
     def get_manipulator_field_objs(self):
         return [formfields.HiddenField]
 
-    def get_manipulator_new_data(self, new_data, rel=False):
+    def get_manipulator_new_data(self, new_data, rel=False, context=None):
         # Never going to be called
         # Not in main change pages
         # ignored in related context
         if not rel:
             return None
-        return Field.get_manipulator_new_data(self, new_data, rel)
+        return Field.get_manipulator_new_data(self, new_data, rel, context)
 
     def contribute_to_class(self, cls, name):
         if cls._meta.has_auto_field:
@@ -440,7 +443,7 @@
     def get_manipulator_field_names(self, name_prefix):
         return [name_prefix + self.name + '_date', name_prefix + self.name + '_time']
 
-    def get_manipulator_new_data(self, new_data, rel=False):
+    def get_manipulator_new_data(self, new_data, rel=False, context=None):
         date_field, time_field = self.get_manipulator_field_names('')
         #if rel:
         #    d = new_data.get(date_field, [None])[0]
Index: django/db/models/related.py
===================================================================
--- django/db/models/related.py	(revision 1817)
+++ django/db/models/related.py	(working copy)
@@ -1,12 +1,12 @@
 from django.db.models.manipulators import ManipulatorCollection
 
 class RelatedManipulatorCollection(ManipulatorCollection):
-    def __init__(self,related, parent_name_parts , instance, follow):
+    def __init__(self, related, parent_name_parts , instance, follow, context=None):
         name_parts = parent_name_parts + (related.var_name, )
         self.instance = instance
         self.related = related
         super(RelatedManipulatorCollection, self).__init__(
-            related.model,follow,name_parts)
+            related.model, follow, name_parts, context)
         
     def _save_child(self, manip, parent_key):
         setattr(manip.original_object, self.related.field.attname, parent_key)
@@ -96,14 +96,14 @@
     def __repr__(self):
         return "<RelatedObject: %s related to %s>" % (self.name, self.field.name)
 
-    def get_fields_and_manipulators(self, opts, manipulator, follow ):
-        return ([], self.get_manipulators(manipulator, follow)  )
+    def get_fields_and_manipulators(self, opts, manipulator, follow, context=None):
+        return ([], self.get_manipulators(manipulator, follow, context)  )
 
-    def get_manipulators(self,parent_manipulator, follow):
+    def get_manipulators(self, parent_manipulator, follow, context=None):
         name_parts = parent_manipulator.name_parts
         obj = parent_manipulator.original_object
         
-        return RelatedManipulatorCollection(self, name_parts, obj, follow)
+        return RelatedManipulatorCollection(self, name_parts, obj, follow, context)
 
     def bind(self, field_mapping, original, bound_related_object_class=BoundRelatedObject):
         return bound_related_object_class(self, field_mapping, original)
Index: django/core/extensions.py
===================================================================
--- django/core/extensions.py	(revision 1817)
+++ django/core/extensions.py	(working copy)
@@ -62,6 +62,34 @@
         for processor in get_standard_processors() + processors:
             self.update(processor(request))
 
+# TODO: should this really be a subclass of template.Context? It should
+# (mostly) behave the same, but really has nothing to do with the template
+# system. Maybe template.Context ought to be moved to just django.core.Context
+class ManipulatorContext(Context):
+    """
+    This subclass of template.Context automatically populates itself using
+    the processors defined in each field's get_context_processors method.
+    Additional processors can be specified as a list of callables
+    using the "processors" keyword argument.
+    """
+    def __init__(self, model, request, dict=None, processors=None):
+        Context.__init__(self, dict)
+
+        standard_processors = []
+        # Get all the processors from the fields in this model.
+        for f in model._meta.fields:
+            field_context_processors = f.get_context_processors()
+            standard_processors.extend(field_context_processors)
+        standard_processors = tuple(standard_processors)
+        if processors is None:
+            processors = ()
+        else:
+            processors = tuple(processors)
+        for processor in standard_processors + processors:
+            self.update(processor(request))
+
+
+
 # PermWrapper and PermLookupDict proxy the permissions system into objects that
 # the template system can understand.
 
Index: django/views/generic/create_update.py
===================================================================
--- django/views/generic/create_update.py	(revision 1817)
+++ django/views/generic/create_update.py	(working copy)
@@ -3,7 +3,7 @@
 from django.core.template import loader
 from django.core import formfields, meta
 from django.views.auth.login import redirect_to_login
-from django.core.extensions import DjangoContext
+from django.core.extensions import DjangoContext, ManipulatorContext
 from django.core.paginator import ObjectPaginator, InvalidPage
 from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect
 from django.core.exceptions import Http404, ObjectDoesNotExist, ImproperlyConfigured
@@ -23,7 +23,8 @@
         return redirect_to_login(request.path)
 
     mod = models.get_module(app_label, module_name)
-    manipulator = mod.AddManipulator(follow=follow)
+    context = ManipulatorContext(mod, request)
+    manipulator = model.AddManipulator(follow=follow, context=context)
     if request.POST:
         # If data was POSTed, we're trying to create a new object
         new_data = request.POST.copy()
@@ -88,6 +89,7 @@
         return redirect_to_login(request.path)
 
     mod = models.get_module(app_label, module_name)
+    context = ManipulatorContext(mod, request)
 
     # Look up the object to be edited
     lookup_kwargs = {}
@@ -103,7 +105,7 @@
     except ObjectDoesNotExist:
         raise Http404("%s.%s does not exist for %s" % (app_label, module_name, lookup_kwargs))
 
-    manipulator = mod.ChangeManipulator(object.id, follow=follow)
+    manipulator = mod.ChangeManipulator(object.id, follow=follow, context=context)
 
     if request.POST:
         new_data = request.POST.copy()
