Index: tests/regressiontests/admin_inlines/tests.py
===================================================================
--- tests/regressiontests/admin_inlines/tests.py	(Revision 16341)
+++ tests/regressiontests/admin_inlines/tests.py	(Arbeitskopie)
@@ -4,7 +4,8 @@
 
 # local test models
 from models import (Holder, Inner, InnerInline, Holder2, Inner2, Holder3,
-    Inner3, Person, OutfitItem, Fashionista, Teacher, Parent, Child)
+    Inner3, Person, OutfitItem, Fashionista, Teacher, Parent, Child, Author2,
+    Book2)
 
 
 class TestInline(TestCase):
@@ -102,6 +103,37 @@
         # The right callabe should be used for the inline readonly_fields
         # column cells
         self.assertContains(response, '<p>Callable in QuestionInline</p>')
+        
+    def test_inline_ids_for_custom_pks(self):
+        """
+        Tests if the hidden input fields for inline element ids are rendered 
+        if the inline model has a custom and non-editable primary key.
+        Refs #13696
+        """
+        # create the sample objects
+        author = Author2.objects.create(name='Terry Goodkind')
+        book = Book2.objects.create(title='Faith of the Fallen', author=author)
+        # navigate to the author creation page
+        response = self.client.get('/test_admin/admin/admin_inlines/author2/add/')
+        self.assertEqual(response.status_code, 200)
+        # assure the inline models of book got a hidden field with id and name
+        # the first stacked inline
+        self.assertRegexpMatches(response.content, r'<input .*(name="book2_set-0-id").*')
+        self.assertRegexpMatches(response.content, r'<input .*(id="id_book2_set-0-id").*')
+        # the second tabular inline
+        self.assertRegexpMatches(response.content, r'<input .*(name="book2_set-2-0-id").*')
+        self.assertRegexpMatches(response.content, r'<input .*(id="id_book2_set-2-0-id").*')
+        # navigate to the author admin site for the created author instance
+        response = self.client.get('/test_admin/admin/admin_inlines/author2/%s/' % author.pk)
+        self.assertEqual(response.status_code, 200)
+        # assure the inline models of book got a hidden field with id and name
+        # the first stacked inline
+        self.assertRegexpMatches(response.content, r'<input .*(name="book2_set-0-id").*')
+        self.assertRegexpMatches(response.content, r'<input .*(id="id_book2_set-0-id").*')
+        # the second tabular inline
+        self.assertRegexpMatches(response.content, r'<input .*(name="book2_set-2-0-id").*')
+        self.assertRegexpMatches(response.content, r'<input .*(id="id_book2_set-2-0-id").*')
+        
 
 class TestInlineMedia(TestCase):
     fixtures = ['admin-views-users.xml']
Index: tests/regressiontests/admin_inlines/models.py
===================================================================
--- tests/regressiontests/admin_inlines/models.py	(Revision 16341)
+++ tests/regressiontests/admin_inlines/models.py	(Arbeitskopie)
@@ -191,3 +191,35 @@
 
 admin.site.register(Poll, PollAdmin)
 admin.site.register(Novel, NovelAdmin)
+
+
+# models for #13696
+class Author2(models.Model):
+    name = models.CharField(max_length=100)
+    
+class Book2(models.Model):
+    id = models.CharField(max_length=32, primary_key=True, editable=False)
+    author = models.ForeignKey(Author2)
+    title = models.CharField(max_length=100)
+
+    def save(self, *args, **kwargs):
+        """
+        Creates a new random id and assigns it to the primary field.
+        """
+        if not self.id:
+            import random
+            self.id = str(random.random())
+        super(Book2, self).save(*args, **kwargs)
+        
+class Book2StackedInline(admin.StackedInline):
+    model = Book2
+    
+class Book2TabularInline(admin.TabularInline):
+    model = Book2
+
+class Author2Admin(admin.ModelAdmin):
+    inlines = [Book2StackedInline, Book2TabularInline]
+    class Meta:
+        model = Author2
+
+admin.site.register(Author2, Author2Admin)
Index: django/contrib/admin/templates/admin/edit_inline/stacked.html
===================================================================
--- django/contrib/admin/templates/admin/edit_inline/stacked.html	(Revision 16341)
+++ django/contrib/admin/templates/admin/edit_inline/stacked.html	(Arbeitskopie)
@@ -13,7 +13,7 @@
   {% for fieldset in inline_admin_form %}
     {% include "admin/includes/fieldset.html" %}
   {% endfor %}
-  {% if inline_admin_form.has_auto_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
+  {% if inline_admin_form.pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
   {{ inline_admin_form.fk_field.field }}
 </div>{% endfor %}
 </div>
Index: django/contrib/admin/templates/admin/edit_inline/tabular.html
===================================================================
--- django/contrib/admin/templates/admin/edit_inline/tabular.html	(Revision 16341)
+++ django/contrib/admin/templates/admin/edit_inline/tabular.html	(Arbeitskopie)
@@ -27,7 +27,7 @@
           {% if inline_admin_form.original %} {{ inline_admin_form.original }}{% endif %}
           {% if inline_admin_form.show_url %}<a href="../../../r/{{ inline_admin_form.original_content_type_id }}/{{ inline_admin_form.original.id }}/">{% trans "View on site" %}</a>{% endif %}
             </p>{% endif %}
-          {% if inline_admin_form.has_auto_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
+          {% if inline_admin_form.pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
           {{ inline_admin_form.fk_field.field }}
           {% spaceless %}
           {% for fieldset in inline_admin_form %}
