diff --git a/django/contrib/admin/templatetags/log.py b/django/contrib/admin/templatetags/log.py
index 463e0792f0..f70ee2731d 100644
--- a/django/contrib/admin/templatetags/log.py
+++ b/django/contrib/admin/templatetags/log.py
@@ -16,8 +16,8 @@ class AdminLogNode(template.Node):
         else:
             user_id = self.user
             if not user_id.isdigit():
-                user_id = context[self.user].id
-            context[self.varname] = LogEntry.objects.filter(user__id__exact=user_id).select_related('content_type', 'user')[:int(self.limit)]
+                user_id = context[self.user].pk
+            context[self.varname] = LogEntry.objects.filter(user__pk__exact=user_id).select_related('content_type', 'user')[:int(self.limit)]
         return ''
 
 @register.tag
diff --git a/tests/admin_changelist/models.py b/tests/admin_changelist/models.py
index 786b4385aa..242e4b7b6c 100644
--- a/tests/admin_changelist/models.py
+++ b/tests/admin_changelist/models.py
@@ -87,3 +87,6 @@ class OrderedObject(models.Model):
     number = models.IntegerField(default=0, db_column='number_val')
 
     objects = OrderedObjectManager()
+
+class CustomIdUser(models.Model):
+    uuid = models.AutoField(primary_key=True)
diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py
index 05cdcdb73d..ce5056e8f0 100644
--- a/tests/admin_changelist/tests.py
+++ b/tests/admin_changelist/tests.py
@@ -20,7 +20,7 @@ from .admin import (ChildAdmin, QuartetAdmin, BandAdmin, ChordsBandAdmin,
     SwallowAdmin, DynamicListFilterChildAdmin)
 from .models import (Event, Child, Parent, Genre, Band, Musician, Group,
     Quartet, Membership, ChordsMusician, ChordsBand, Invitation, Swallow,
-    UnorderedObject, OrderedObject)
+    UnorderedObject, OrderedObject, CustomIdUser)
 
 
 class ChangeListTests(TestCase):
@@ -563,3 +563,22 @@ class ChangeListTests(TestCase):
         request = self._mocked_authenticated_request('/child/', user_parents)
         response = m.changelist_view(request)
         self.assertEqual(response.context_data['cl'].list_filter, ('parent', 'name', 'age'))
+
+class AdminLogNodeTestCase(TestCase):
+
+    def test_get_admin_log_templatetag_custom_user(self):
+        """
+        Regression test for ticket #20088: admin log depends on User model
+        having id field as primary key.
+
+        The old implementation raised an AttributeError when trying to use
+        the id field.
+        """
+        context = Context({'user': CustomIdUser()})
+        template_string = '{% load log %}{% get_admin_log 10 as admin_log for_user user %}'
+
+        template = Template(template_string)
+
+        # Rendering should be u'' since this templatetag just logs,
+        # it doesn't render any string.
+        self.assertEquals(template.render(context), u'')