Index: django/contrib/admin/views/main.py
===================================================================
--- django/contrib/admin/views/main.py	(revision 1783)
+++ django/contrib/admin/views/main.py	(working copy)
@@ -396,7 +396,10 @@
     mod, opts = _get_mod_opts(app_label, module_name)
     if not request.user.has_perm(app_label + '.' + opts.get_add_permission()):
         raise PermissionDenied
-    manipulator = mod.AddManipulator()
+    # Create the context here so the manipulator can access it.
+    c = Context(request, {})
+    manipulator = mod.AddManipulator(context=c)
+
     if request.POST:
         new_data = request.POST.copy()
         if opts.has_field_type(meta.FileField):
@@ -437,12 +440,13 @@
     # Populate the FormWrapper.
     form = formfields.FormWrapper(manipulator, new_data, errors, edit_inline=True)
 
-    c = Context(request, {
+    extra_context = {
         'title': _('Add %s') % opts.verbose_name,
         'form': form,
         'is_popup': request.REQUEST.has_key('_popup'),
         'show_delete': show_delete,
-    })
+    }
+    c.update(extra_context)
     if object_id_override is not None:
         c['object_id'] = object_id_override
 
@@ -471,7 +475,9 @@
     if request.POST and request.POST.has_key("_saveasnew"):
         return add_stage(request, app_label, module_name, form_url='../add/')
     try:
-        manipulator = mod.ChangeManipulator(object_id)
+        # Create the context here so the manipulator can access it.
+        c = Context(request)
+        manipulator = mod.ChangeManipulator(object_id, context=c)
     except ObjectDoesNotExist:
         raise Http404
 
@@ -532,14 +538,14 @@
             orig_list = func()
             form.order_objects.extend(orig_list)
 
-    c = Context(request, {
+    extra_context = {
         'title': _('Change %s') % opts.verbose_name,
         'form': form,
         'object_id': object_id,
         'original': manipulator.original_object,
         'is_popup' : request.REQUEST.has_key('_popup')
-    })
-
+    }
+    c.update(extra_context)
     return render_change_form(opts,manipulator, app_label, c, change=True)
 
 def _nest_help(obj, depth, val):
Index: django/core/meta/fields.py
===================================================================
--- django/core/meta/fields.py	(revision 1783)
+++ django/core/meta/fields.py	(working copy)
@@ -197,7 +197,7 @@
         "Returns a boolean of whether this field has a default value."
         return self.default != NOT_PROVIDED
 
-    def get_default(self):
+    def get_default(self, context=None):
         "Returns the default value for this field."
         if self.default != NOT_PROVIDED:
             if hasattr(self.default, '__get_value__'):
@@ -293,15 +293,15 @@
         field_names = self.get_manipulator_field_names(name_prefix)
         return [man(field_name=field_names[i], **params) for i, man in enumerate(field_objs)]
 
-    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.
         """
         if rel:
-            return new_data.get(self.name, [self.get_default()])[0]
+            return new_data.get(self.name, [self.get_default(context)])[0]
         else:
-            val = new_data.get(self.name, self.get_default())
+            val = new_data.get(self.name, self.get_default(context))
             if not self.empty_strings_allowed and val == '' and self.null:
                 val = None
             return val
@@ -358,10 +358,10 @@
     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):
         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)
 
 class BooleanField(Field):
     def __init__(self, *args, **kwargs):
@@ -438,7 +438,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]
@@ -741,6 +741,31 @@
                     return {self.attname: choice_list[1][0]}
         return Field.flatten_data(self, follow, obj)
 
+class CurrentUserField(ForeignKey):
+    def __init__(self, to=None, update_on_edit=True, **kwargs):
+        self.update_on_edit = update_on_edit
+        if to is None:
+            from django.models.auth.users import User
+            to = User
+        # TODO: should these be overridable? I can't think of a reason why
+        # it would be necessary to do so.
+        kwargs['blank'] = True
+        kwargs['null'] = True
+        kwargs['editable'] = False
+        ForeignKey.__init__(self, to, **kwargs)
+
+    def get_default(self, context=None):
+        if context is not None:
+            return context['user'].id
+        else:
+            return None
+
+    def get_follow(self, override=None):
+        if override != None:
+            return override
+        else:
+            return True
+
 class ManyToManyField(Field):
     def __init__(self, to, **kwargs):
         kwargs['verbose_name'] = kwargs.get('verbose_name', to._meta.verbose_name_plural)
Index: django/core/meta/__init__.py
===================================================================
--- django/core/meta/__init__.py	(revision 1783)
+++ django/core/meta/__init__.py	(working copy)
@@ -1709,8 +1709,9 @@
         setattr(man, k, v)
     return man
 
-def manipulator_init(opts, add, change, self, obj_key=None, follow=None):
+def manipulator_init(opts, add, change, self, obj_key=None, follow=None, context=None):
     self.follow = opts.get_follow(follow)
+    self.context = context
 
     if change:
         assert obj_key is not None, "ChangeManipulator.__init__() must be passed obj_key parameter."
@@ -1758,7 +1759,7 @@
         # Fields with auto_now_add should keep their original value in the change stage.
         auto_now_add = 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(new_data)
+            param = f.get_manipulator_new_data(new_data, context=self.context)
         else:
             if change:
                 param = getattr(self.original_object, f.attname)
@@ -1833,9 +1834,9 @@
                             pass
 
                 for f in related.opts.fields:
-                    if f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) in (None, ''):
+                    if f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True, context=self.context) in (None, ''):
                         all_cores_given = False
-                    elif f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True) not in (None, ''):
+                    elif f.core and not isinstance(f, FileField) and f.get_manipulator_new_data(rel_new_data, rel=True, context=self.context) not in (None, ''):
                         all_cores_blank = False
                     # If this field isn't editable, give it the same value it had
                     # previously, according to the given ID. If the ID wasn't
@@ -1852,7 +1853,7 @@
                         else:
                             param = f.get_default()
                     else:
-                        param = f.get_manipulator_new_data(rel_new_data, rel=True)
+                        param = f.get_manipulator_new_data(rel_new_data, rel=True, context=context)
                     if param != None:
                        params[f.attname] = param
 
