Index: django/contrib/admin/views/stages/add.py
===================================================================
--- django/contrib/admin/views/stages/add.py	(revision 1798)
+++ django/contrib/admin/views/stages/add.py	(working copy)
@@ -22,7 +22,8 @@
 
     if not request.user.has_perm(app_label + '.' + opts.get_add_permission()):
         raise PermissionDenied
-    manipulator = model.AddManipulator()
+    c = Context(request)
+    manipulator = model.AddManipulator(context=c)
     if request.POST:
         new_data = request.POST.copy()
         if opts.has_field_type(models.FileField):
@@ -78,13 +79,14 @@
     # Populate the FormWrapper.
     form = formfields.FormWrapper(manipulator, new_data, errors)
 
-    c = Context(request, {
+    extra_context = {
         'title': _('Add %s') % opts.verbose_name,
         'form': form,
         'is_popup': request.REQUEST.has_key('_popup'),
         'show_delete': show_delete,
         'path': path ,
-    })
+    }
+    c.update(extra_context)
 
     if object_id_override is not None:
         c['object_id'] = object_id_override
Index: django/contrib/admin/views/stages/change.py
===================================================================
--- django/contrib/admin/views/stages/change.py	(revision 1798)
+++ django/contrib/admin/views/stages/change.py	(working copy)
@@ -38,7 +38,8 @@
         return add_stage(request, path, form_url='../../add/')
     
     try:
-        manipulator = model.ChangeManipulator(object_id)
+        c = Context(request)
+        manipulator = model.ChangeManipulator(object_id, context=c)
     except ObjectDoesNotExist:
         raise Http404
 
@@ -96,12 +97,13 @@
     form.original = manipulator.original_object
     form.order_objects = []
 
-    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'),
         'path': path ,
-    })
+    }
+    c.update(extra_context)
     return render_change_form(model, manipulator, app_label, c, change=True)
Index: django/db/models/manipulators.py
===================================================================
--- django/db/models/manipulators.py	(revision 1798)
+++ django/db/models/manipulators.py	(working copy)
@@ -82,7 +82,8 @@
         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):
+        self.context = context
         Naming.__init__(self, name_parts)
         if name_parts == ():
             self.follow = self.model._meta.get_follow(follow)
@@ -142,10 +143,10 @@
             if over:
                 param = over
             else:
-                # 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)
+                # Fields with allow_updates=False should keep their original value in the change stage.
+                allow_updates = self.add or getattr(f, 'allow_updates', True)
+                if self.follow.get(f.name, None) and allow_updates:
+                    param = f.get_manipulator_new_data(expanded_data, context=self.context)
                 else:
                     param = self.get_original_value(f)
             params[f.attname] = param
@@ -280,11 +281,11 @@
 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()
+        return field.get_default(context=self.context)
     
     def __repr__(self):
         return "<Automatic AddManipulator '%s' for %s>" % (self.name_prefix, self.model.__name__, )
@@ -293,7 +294,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 +322,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():
Index: django/db/models/fields/__init__.py
===================================================================
--- django/db/models/fields/__init__.py	(revision 1798)
+++ django/db/models/fields/__init__.py	(working copy)
@@ -185,7 +185,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__'):
@@ -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.
@@ -286,7 +286,7 @@
         #if rel:
         #    return new_data.get(self.name, [self.get_default()])[0]
         #else:
-        val = new_data.get(self.name, self.get_default())
+        val = new_data.get(self.name, self.get_default(context=context))
         if not self.empty_strings_allowed and val == '' and self.null:
             val = None
         return val
@@ -343,13 +343,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:
@@ -377,6 +377,8 @@
     empty_strings_allowed = False
     def __init__(self, verbose_name=None, name=None, auto_now=False, auto_now_add=False, **kwargs):
         self.auto_now, self.auto_now_add = auto_now, auto_now_add
+        # If auto_now_add is True, we don't want to allow updates to this field.
+        self.allow_updates = not auto_now_add
         #HACKs : auto_now_add/auto_now should be done as a default or a pre_save.
         if auto_now or auto_now_add:
             kwargs['editable'] = False
@@ -440,7 +442,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/fields/related.py
===================================================================
--- django/db/models/fields/related.py	(revision 1798)
+++ django/db/models/fields/related.py	(working copy)
@@ -382,3 +382,28 @@
         self.edit_inline = False
         self.raw_id_admin = raw_id_admin
         assert not (self.raw_id_admin and self.filter_interface), "ManyToMany relationships may not use both raw_id_admin and filter_interface"
+
+class CurrentUserField(ForeignKey):
+    def __init__(self, to=None, allow_updates=True, **kwargs):
+        self.allow_updates = allow_updates
+        if to is None:
+            from django.models.auth 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
