diff --git a/tjdests/apps/authentication/admin.py b/tjdests/apps/authentication/admin.py
index 96c37a5..ee47e52 100644
--- a/tjdests/apps/authentication/admin.py
+++ b/tjdests/apps/authentication/admin.py
@@ -4,8 +4,8 @@ from .models import User
 
 
 class UserAdmin(admin.ModelAdmin):
-    search_fields = ["username", "first_name", "last_name"]
-    list_display = ["username", "last_name", "first_name", "last_modified"]
+    search_fields = ["username", "preferred_name", "last_name"]
+    list_display = ["username", "last_name", "preferred_name", "last_modified"]
     list_filter = ["is_senior", "is_student", "accepted_terms", "publish_data"]
 
     fieldsets = (
@@ -14,8 +14,9 @@ class UserAdmin(admin.ModelAdmin):
             {
                 "fields": (
                     "username",
-                    "first_name",
+                    "preferred_name",
                     "last_name",
+                    "nickname",
                     "email",
                     "password",
                     "accepted_terms",
diff --git a/tjdests/apps/authentication/migrations/0010_user_nickname.py b/tjdests/apps/authentication/migrations/0010_user_nickname.py
new file mode 100644
index 0000000..72da575
--- /dev/null
+++ b/tjdests/apps/authentication/migrations/0010_user_nickname.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.5 on 2021-07-28 02:07
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("authentication", "0009_user_last_modified"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="user",
+            name="nickname",
+            field=models.CharField(blank=True, max_length=30),
+        ),
+    ]
diff --git a/tjdests/apps/authentication/models.py b/tjdests/apps/authentication/models.py
index 60a6098..19484be 100644
--- a/tjdests/apps/authentication/models.py
+++ b/tjdests/apps/authentication/models.py
@@ -13,6 +13,8 @@ class User(AbstractUser):
     is_senior = models.BooleanField(default=False)
     is_student = models.BooleanField(default=False)
 
+    nickname = models.CharField(max_length=30, blank=True)
+
     # The rest are used only if a senior
     publish_data = models.BooleanField(
         default=False,
@@ -33,5 +35,9 @@ class User(AbstractUser):
 
     last_modified = models.DateTimeField(auto_now=True)
 
+    @property
+    def preferred_name(self):
+        return self.nickname if self.nickname else self.first_name
+
     def __str__(self):
-        return f"{self.first_name} {self.last_name}"
+        return f"{self.preferred_name} {self.last_name}"
diff --git a/tjdests/apps/authentication/oauth.py b/tjdests/apps/authentication/oauth.py
index 10374b2..98fece1 100644
--- a/tjdests/apps/authentication/oauth.py
+++ b/tjdests/apps/authentication/oauth.py
@@ -28,6 +28,7 @@ class IonOauth2(BaseOAuth2):  # pylint: disable=abstract-method
             "username": profile["ion_username"],
             "first_name": profile["first_name"],
             "last_name": profile["last_name"],
+            "nickname": profile["nickname"] if profile["nickname"] else "",
             "full_name": profile["full_name"],
             "email": profile["tj_email"],
             "is_student": profile["is_student"],
diff --git a/tjdests/apps/destinations/tests.py b/tjdests/apps/destinations/tests.py
index abede51..030e7f1 100644
--- a/tjdests/apps/destinations/tests.py
+++ b/tjdests/apps/destinations/tests.py
@@ -58,6 +58,7 @@ class DestinationsTest(TJDestsTestCase):
         )
         user2.first_name = "Adam"
         user2.last_name = "William"
+        user2.nickname = "John"
         user2.save()
 
         college2 = College.objects.get_or_create(name="university of test")[0]
@@ -114,11 +115,18 @@ class DestinationsTest(TJDestsTestCase):
         self.assertIn(user, response.context["object_list"])
         self.assertNotIn(user2, response.context["object_list"])
 
+        # Adam "John" William should show up when searching "Adam", his first name...
         response = self.client.get(reverse("destinations:students"), data={"q": "Adam"})
         self.assertEqual(200, response.status_code)
         self.assertNotIn(user, response.context["object_list"])
         self.assertIn(user2, response.context["object_list"])
 
+        # ...and he should show up when searching "John", his middle name
+        response = self.client.get(reverse("destinations:students"), data={"q": "John"})
+        self.assertEqual(200, response.status_code)
+        self.assertNotIn(user, response.context["object_list"])
+        self.assertIn(user2, response.context["object_list"])
+
         response = self.client.get(
             reverse("destinations:students"), data={"q": "William"}
         )
diff --git a/tjdests/apps/destinations/views.py b/tjdests/apps/destinations/views.py
index 34bcf5e..629b3ac 100644
--- a/tjdests/apps/destinations/views.py
+++ b/tjdests/apps/destinations/views.py
@@ -42,6 +42,7 @@ class StudentDestinationListView(
             queryset = queryset.filter(
                 Q(first_name__icontains=search_query)
                 | Q(last_name__icontains=search_query)
+                | Q(nickname__icontains=search_query)
                 | Q(biography__icontains=search_query)
             )
 
diff --git a/tjdests/templates/profile/profile.html b/tjdests/templates/profile/profile.html
index 1b6ca68..a83aeda 100644
--- a/tjdests/templates/profile/profile.html
+++ b/tjdests/templates/profile/profile.html
@@ -4,7 +4,7 @@
 
 {% block content %}
     <h2>Profile</h2>
-    <p>You are {{ request.user.username }}, {{ request.user.first_name }} {{ request.user.last_name }}.</p>
+    <p>You are {{ request.user.username }}, {{ request.user.preferred_name }} {{ request.user.last_name }}.</p>
 
     <h4>Data Publication, College Attending, Biography</h4>
     <div class="container">