diff -r f681ed7ea9ad django/db/models/fields/related.py
--- a/django/db/models/fields/related.py	Sun Apr 25 13:18:24 2010 +0000
+++ b/django/db/models/fields/related.py	Mon Apr 26 21:37:59 2010 +0800
@@ -824,14 +824,9 @@
     def validate(self, value, model_instance):
         if self.rel.parent_link:
             return
-        # Don't validate the field if a value wasn't supplied. This is
-        # generally the case when saving new inlines in the admin.
-        # See #12507.
+        super(ForeignKey, self).validate(value, model_instance)
         if value is None:
             return
-        super(ForeignKey, self).validate(value, model_instance)
-        if not value:
-            return
 
         qs = self.rel.to._default_manager.filter(**{self.rel.field_name:value})
         qs = qs.complex_filter(self.rel.limit_choices_to)
diff -r f681ed7ea9ad django/forms/models.py
--- a/django/forms/models.py	Sun Apr 25 13:18:24 2010 +0000
+++ b/django/forms/models.py	Mon Apr 26 21:37:59 2010 +0800
@@ -316,12 +316,23 @@
         return self.cleaned_data
 
     def _post_clean(self):
-        exclude = self._get_validation_exclusions()
         opts = self._meta
-
         # Update the model instance with self.cleaned_data.
         self.instance = construct_instance(self, self.instance, opts.fields, opts.exclude)
 
+        exclude = self._get_validation_exclusions()
+
+        # Foreign Keys being used to represent inline relationships
+        # are excluded from basic field value validation. This is for two
+        # reasons: firstly, the value may not be supplied (#12507; the
+        # case of providing new values to the admin); secondly the
+        # object being referred to may not yet fully exist (#12749).
+        # However, these fields *must* be included in uniqueness checks,
+        # so this can't be part of _get_validation_exclusions().
+        for f_name, field in self.fields.items():
+            if isinstance(field, InlineForeignKeyField):
+                exclude.append(f_name)
+
         # Clean the model instance's fields.
         try:
             self.instance.clean_fields(exclude=exclude)
@@ -762,6 +773,7 @@
         unique_check = [field for field in unique_check if field != self.fk.name]
         return super(BaseInlineFormSet, self).get_unique_error_message(unique_check)
 
+
 def _get_foreign_key(parent_model, model, fk_name=None, can_fail=False):
     """
     Finds and returns the ForeignKey from model to parent if there is one
diff -r f681ed7ea9ad tests/regressiontests/admin_inlines/models.py
--- a/tests/regressiontests/admin_inlines/models.py	Sun Apr 25 13:18:24 2010 +0000
+++ b/tests/regressiontests/admin_inlines/models.py	Mon Apr 26 21:37:59 2010 +0800
@@ -88,6 +88,29 @@
 # only Inline media
 admin.site.register(Holder3, inlines=[InnerInline3])
 
+# Models for #12749
+
+class Person(models.Model):
+    firstname = models.CharField(max_length=15)
+
+class OutfitItem(models.Model):
+    name = models.CharField(max_length=15)
+
+class Fashionista(models.Model):
+    person = models.OneToOneField(Person, primary_key=True)
+    weaknesses = models.ManyToManyField(OutfitItem, through='ShoppingWeakness', blank=True)
+
+class ShoppingWeakness(models.Model):
+    fashionista = models.ForeignKey(Fashionista)
+    item = models.ForeignKey(OutfitItem)
+
+class InlineWeakness(admin.TabularInline):
+    model = ShoppingWeakness
+    extra = 1
+
+admin.site.register(Fashionista, inlines=[InlineWeakness])
+
+
 __test__ = {'API_TESTS': """
 
 # Regression test for #9362
diff -r f681ed7ea9ad tests/regressiontests/admin_inlines/tests.py
--- a/tests/regressiontests/admin_inlines/tests.py	Sun Apr 25 13:18:24 2010 +0000
+++ b/tests/regressiontests/admin_inlines/tests.py	Mon Apr 26 21:37:59 2010 +0800
@@ -3,7 +3,7 @@
 # local test models
 from models import Holder, Inner, InnerInline
 from models import Holder2, Inner2, Holder3, Inner3
-
+from models import Person, OutfitItem, Fashionista
 
 class TestInline(TestCase):
     fixtures = ['admin-views-users.xml']
@@ -38,6 +38,22 @@
                                    % holder.id)
         self.assertContains(response, '<label>Inner readonly label:</label>')
 
+    def test_inline_primary(self):
+        person = Person.objects.create(firstname='Imelda')
+        item = OutfitItem.objects.create(name='Shoes')
+        # Imelda likes shoes, but can't cary her own bags.
+        data = {
+            'shoppingweakness_set-TOTAL_FORMS': 1,
+            'shoppingweakness_set-INITIAL_FORMS': 0,
+            'shoppingweakness_set-MAX_NUM_FORMS': 0,
+            '_save': u'Save',
+            'person': person.id,
+            'max_weight': 0,
+            'shoppingweakness_set-0-item': item.id,
+        }
+        response = self.client.post('/test_admin/admin/admin_inlines/fashionista/add/', data)
+        self.assertEqual(response.status_code, 302)
+        self.assertEqual(len(Fashionista.objects.filter(person__firstname='Imelda')), 1)
 
 class TestInlineMedia(TestCase):
     fixtures = ['admin-views-users.xml']
