Index: django/db/models/base.py
===================================================================
--- django/db/models/base.py	(revision 7003)
+++ django/db/models/base.py	(working copy)
@@ -165,6 +165,13 @@
                 val = field.get_default()
             setattr(self, field.attname, val)
 
+        for item in dir(self):
+            if item.startswith('choices_for__'):
+                choice_func = getattr(self,item)
+                if callable(choice_func):
+                    field_name = choice_func.__name__[len('choices_for__'):]
+                    self._meta.get_field(field_name)._choices = choice_func
+        
         if kwargs:
             for prop in kwargs.keys():
                 try:
Index: django/db/models/fields/__init__.py
===================================================================
--- django/db/models/fields/__init__.py	(revision 7003)
+++ django/db/models/fields/__init__.py	(working copy)
@@ -8,6 +8,7 @@
 
 from django.db import get_creation_module
 from django.db.models import signals
+import django.db.models.query
 from django.dispatch import dispatcher
 from django.conf import settings
 from django.core import validators
@@ -338,7 +339,15 @@
         "Returns a list of tuples used as SelectField choices for this field."
         first_choice = include_blank and blank_choice or []
         if self.choices:
-            return first_choice + list(self.choices)
+            if callable(self.choices):
+                choices = self.choices()
+            else:
+                choices = self.choices
+            # If choices is a QuerySet, convert into a tuple list ((pk,__unicode__),etc)
+            if isinstance(choices, django.db.models.query.QuerySet):
+                choices = [(x._get_pk_val(), smart_unicode(x)) for x in choices]
+            return first_choice + list(choices)
+            
         rel_model = self.rel.to
         if hasattr(self.rel, 'get_related_field'):
             lst = [(getattr(x, self.rel.get_related_field().attname), smart_unicode(x)) for x in rel_model._default_manager.complex_filter(self.rel.limit_choices_to)]
@@ -391,6 +400,7 @@
         defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text}
         if self.choices:
             defaults['widget'] = forms.Select(choices=self.get_choices(include_blank=self.blank or not (self.has_default() or 'initial' in kwargs)))
+            kwargs['queryset'] = self.choices()
         if self.has_default():
             defaults['initial'] = self.get_default()
         defaults.update(kwargs)
