Index: django/contrib/admin/options.py
===================================================================
--- django/contrib/admin/options.py	(revision 11612)
+++ django/contrib/admin/options.py	(working copy)
@@ -58,6 +58,7 @@
     fields = None
     exclude = None
     fieldsets = None
+    dynamic_fieldsets = None
     form = forms.ModelForm
     filter_vertical = ()
     filter_horizontal = ()
@@ -318,6 +319,8 @@
 
     def get_fieldsets(self, request, obj=None):
         "Hook for specifying fieldsets for the add form."
+        if self.dynamic_fieldsets:
+            self.dynamic_fieldsets(request, obj)
         if self.declared_fieldsets:
             return self.declared_fieldsets
         form = self.get_form(request, obj)
@@ -328,7 +331,9 @@
         Returns a Form class for use in the admin add view. This is used by
         add_view and change_view.
         """
-        if self.declared_fieldsets:
+        if self.dynamic_fieldsets:
+            fields = flatten_fieldsets(self.dynamic_fieldsets(request, obj, **kwargs))
+        elif self.declared_fieldsets:
             fields = flatten_fieldsets(self.declared_fieldsets)
         else:
             fields = None
@@ -1136,6 +1141,8 @@
 
     def get_formset(self, request, obj=None, **kwargs):
         """Returns a BaseInlineFormSet class for use in admin add/change views."""
+        if self.dynamic_fieldsets:
+            fields = flatten_fieldsets(self.dynamic_fieldsets(request, obj))
         if self.declared_fieldsets:
             fields = flatten_fieldsets(self.declared_fieldsets)
         else:
@@ -1160,6 +1167,8 @@
         return inlineformset_factory(self.parent_model, self.model, **defaults)
 
     def get_fieldsets(self, request, obj=None):
+        if self.dynamic_fieldsets:
+            return self.dynamic_fieldsets(request, obj)
         if self.declared_fieldsets:
             return self.declared_fieldsets
         form = self.get_formset(request).form
