diff --git a/django/forms/models.py b/django/forms/models.py
index 0039516..866cacd 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -276,10 +276,18 @@ class BaseModelForm(BaseForm):
             # adding these values to the model after form validation.
             if field not in self.fields:
                 exclude.append(f.name)
+
+            # if some fields were excluded, don't run their validation
+            # this is needed on top of previous line to catch fields added onto
+            # the form with same name as some model field
+            elif self._meta.fields and field not in self._meta.fields:
+                exclude.append(f.name)
+
             # Exclude fields that failed form validation. There's no need for
             # the model fields to validate them as well.
             elif field in self._errors.keys():
                 exclude.append(f.name)
+
             # Exclude empty fields that are not required by the form. The
             # underlying model field may be required, so this keeps the model
             # field from raising that error.
@@ -719,16 +727,26 @@ class BaseInlineFormSet(BaseModelFormSet):
     def add_fields(self, form, index):
         super(BaseInlineFormSet, self).add_fields(form, index)
         if self._pk_field == self.fk:
-            form.fields[self._pk_field.name] = InlineForeignKeyField(self.instance, pk_field=True)
+            name = self._pk_field.name
+            kwargs = {'pk_field': True}
         else:
             # The foreign key field might not be on the form, so we poke at the
             # Model field to get the label, since we need that for error messages.
+            name = self.fk.name
             kwargs = {
-                'label': getattr(form.fields.get(self.fk.name), 'label', capfirst(self.fk.verbose_name))
+                'label': getattr(form.fields.get(name), 'label', capfirst(self.fk.verbose_name))
             }
             if self.fk.rel.field_name != self.fk.rel.to._meta.pk.name:
                 kwargs['to_field'] = self.fk.rel.field_name
-            form.fields[self.fk.name] = InlineForeignKeyField(self.instance, **kwargs)
+
+        form.fields[name] = InlineForeignKeyField(self.instance, **kwargs)
+
+        # add the generated field to form._meta.fields if defined to make sure
+        # validation isn't skipped on that field
+        if form._meta.fields:
+            if isinstance(form._meta.fields, tuple):
+                form._meta.fields = list(form._meta.fields)
+            form._meta.fields.append(self.fk.name)
 
     def get_unique_error_message(self, unique_check):
         unique_check = [field for field in unique_check if field != self.fk.name]
diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py
index b8b826a..12a39b5 100644
--- a/tests/modeltests/model_forms/models.py
+++ b/tests/modeltests/model_forms/models.py
@@ -9,9 +9,12 @@ words, most of these tests should be rewritten.
 
 import os
 import tempfile
+from unittest import TestCase
 
 from django.db import models
 from django.core.files.storage import FileSystemStorage
+from django import forms
+from django.forms.models import ModelForm
 
 temp_storage_dir = tempfile.mkdtemp()
 temp_storage = FileSystemStorage(temp_storage_dir)
@@ -205,6 +208,18 @@ class BigInt(models.Model):
     def __unicode__(self):
         return unicode(self.biggie)
 
+class IncompleteCategoryForm(ModelForm):
+    url = forms.CharField(required=False)
+
+    class Meta:
+        fields = ('name', 'slug')
+        model = Category
+
+class TestCase(TestCase):
+    def test_category_doesnt_validate_url_when_not_on_modelform(self):
+        form = IncompleteCategoryForm(data={'name': 'some name', 'slug': 'some-slug'})
+        assert form.is_valid()
+
 __test__ = {'API_TESTS': """
 >>> from django import forms
 >>> from django.forms.models import ModelForm, model_to_dict
