Index: django/newforms/models.py
===================================================================
--- django/newforms/models.py	(revision 7003)
+++ django/newforms/models.py	(working copy)
@@ -11,7 +11,7 @@
 from django.core.exceptions import ImproperlyConfigured
 
 from util import ValidationError, ErrorList
-from forms import BaseForm
+from forms import BaseForm, get_declared_fields
 from fields import Field, ChoiceField, EMPTY_VALUES
 from widgets import Select, SelectMultiple, MultipleHiddenInput
 
@@ -214,49 +214,38 @@
 class ModelFormMetaclass(type):
     def __new__(cls, name, bases, attrs,
                 formfield_callback=lambda f: f.formfield()):
-        fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, Field)]
-        fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter))
 
-        # If this class is subclassing another Form, add that Form's fields.
-        # Note that we loop over the bases in *reverse*. This is necessary in
-        # order to preserve the correct order of fields.
-        for base in bases[::-1]:
-            if hasattr(base, 'base_fields'):
-                fields = base.base_fields.items() + fields
-        declared_fields = SortedDict(fields)
+        fields = SortedDict()
 
-        opts = ModelFormOptions(attrs.get('Meta', None))
-        attrs['_meta'] = opts
-
-        # Don't allow more than one Meta model defenition in bases. The fields
-        # would be generated correctly, but the save method won't deal with
-        # more than one object.
-        base_models = []
-        for base in bases:
-            base_opts = getattr(base, '_meta', None)
-            base_model = getattr(base_opts, 'model', None)
-            if base_model is not None:
-                base_models.append(base_model)
-        if len(base_models) > 1:
-            raise ImproperlyConfigured("%s's base classes define more than one model." % name)
-
-        # If a model is defined, extract form fields from it and add them to base_fields
-        if attrs['_meta'].model is not None:
-            # Don't allow a subclass to define a different Meta model than a
-            # parent class has. Technically the right fields would be generated,
-            # but the save method will not deal with more than one model.
+        meta = attrs.get('Meta', None)
+        if meta is not None:
+            opts = ModelFormOptions(meta)
+            # If a model is defined, extract form fields from it
+            if opts.model is not None:
+                fields = fields_for_model(opts.model, opts.fields,
+                                          opts.exclude, formfield_callback)
+        else:
+            # No Meta options defined in the class. Search base classes, but
+            # don't allow more than one Meta definition. The fields would be
+            # generated correctly, but the save method won't deal with more
+            # than one object. Also, it wouldn't be clear what to do with
+            # multiple fields and exclude lists.
+            opts = None
             for base in bases:
                 base_opts = getattr(base, '_meta', None)
-                base_model = getattr(base_opts, 'model', None)
-                if base_model and base_model is not opts.model:
-                    raise ImproperlyConfigured('%s defines a different model than its parent.' % name)
-            model_fields = fields_for_model(opts.model, opts.fields,
-                    opts.exclude, formfield_callback)
-            # fields declared in base classes override fields from the model
-            model_fields.update(declared_fields)
-            attrs['base_fields'] = model_fields
-        else:
-            attrs['base_fields'] = declared_fields
+                if base_opts is not None:
+                    if opts is not None: 
+                        raise ImproperlyConfigured("%s's base classes define more than one Meta options." % name)
+                    opts = base_opts 
+            if opts is None:
+                # No Meta options defined neither in the class nor its base classes
+                opts = ModelFormOptions()
+
+        attrs['_meta'] = opts
+
+        # Fields declared explicitely override fields from the model
+        fields.update(get_declared_fields(bases, attrs))
+        attrs['base_fields'] = fields
         return type.__new__(cls, name, bases, attrs)
 
 class BaseModelForm(BaseForm):
Index: django/newforms/forms.py
===================================================================
--- django/newforms/forms.py	(revision 7003)
+++ django/newforms/forms.py	(working copy)
@@ -22,23 +22,26 @@
     name = name[0].upper() + name[1:]
     return name.replace('_', ' ')
 
+def get_declared_fields(bases, attrs):
+    fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, Field)]
+    fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter))
+
+    # If this class is subclassing another Form, add that Form's fields.
+    # Note that we loop over the bases in *reverse*. This is necessary in
+    # order to preserve the correct order of fields.
+    for base in bases[::-1]:
+        if hasattr(base, 'base_fields'):
+            fields = base.base_fields.items() + fields
+
+    return SortedDict(fields)
+
 class DeclarativeFieldsMetaclass(type):
     """
     Metaclass that converts Field attributes to a dictionary called
     'base_fields', taking into account parent class 'base_fields' as well.
     """
     def __new__(cls, name, bases, attrs):
-        fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, Field)]
-        fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter))
-
-        # If this class is subclassing another Form, add that Form's fields.
-        # Note that we loop over the bases in *reverse*. This is necessary in
-        # order to preserve the correct order of fields.
-        for base in bases[::-1]:
-            if hasattr(base, 'base_fields'):
-                fields = base.base_fields.items() + fields
-
-        attrs['base_fields'] = SortedDict(fields)
+        attrs['base_fields'] = get_declared_fields(bases, attrs)
         return type.__new__(cls, name, bases, attrs)
 
 class BaseForm(StrAndUnicode):
Index: docs/modelforms.txt
===================================================================
--- docs/modelforms.txt	(revision 7003)
+++ docs/modelforms.txt	(working copy)
@@ -311,3 +311,11 @@
     ...
     ...     class Meta:
     ...         model = Article
+
+Form inheritance
+----------------
+As with the basic forms, you can extend and reuse forms by inheriting them.
+The fields will be combined, but only the most recently declared Meta
+definition will be used. If you do not include a Meta definition in a child
+class, a Meta definition will be looked in its parent classes. Note that it is
+not allowed to have more than one base class with the Meta defition.
