diff --git a/symposion/reviews/urls.py b/symposion/reviews/urls.py
index ba100c71..0ecc34e2 100644
--- a/symposion/reviews/urls.py
+++ b/symposion/reviews/urls.py
@@ -9,6 +9,7 @@ from .views import (
     result_notification,
     result_notification_prepare,
     result_notification_send,
+    review_random_proposal,
     review_detail,
     review_delete,
     review_assignments,
@@ -19,6 +20,7 @@ urlpatterns = [
     url(r"^section/(?P<section_slug>[\w\-]+)/all/$", review_section, {"reviewed": "all"}, name="review_section"),
     url(r"^section/(?P<section_slug>[\w\-]+)/reviewed/$", review_section, {"reviewed": "reviewed"}, name="user_reviewed"),
     url(r"^section/(?P<section_slug>[\w\-]+)/not_reviewed/$", review_section, {"reviewed": "not_reviewed"}, name="user_not_reviewed"),
+    url(r"^section/(?P<section_slug>[\w\-]+)/random/$", review_random_proposal, name="user_random"),
     url(r"^section/(?P<section_slug>[\w\-]+)/assignments/$", review_section, {"assigned": True}, name="review_section_assignments"),
     url(r"^section/(?P<section_slug>[\w\-]+)/status/$", review_status, name="review_status"),
     url(r"^section/(?P<section_slug>[\w\-]+)/status/(?P<key>\w+)/$", review_status, name="review_status"),
@@ -29,6 +31,7 @@ urlpatterns = [
     url(r"^section/(?P<section_slug>[\w\-]+)/notification/(?P<status>\w+)/prepare/$", result_notification_prepare, name="result_notification_prepare"),
     url(r"^section/(?P<section_slug>[\w\-]+)/notification/(?P<status>\w+)/send/$", result_notification_send, name="result_notification_send"),
 
+
     url(r"^review/(?P<pk>\d+)/$", review_detail, name="review_detail"),
 
     url(r"^(?P<pk>\d+)/delete/$", review_delete, name="review_delete"),
diff --git a/symposion/reviews/views.py b/symposion/reviews/views.py
index c1ece5bb..dc6d969a 100644
--- a/symposion/reviews/views.py
+++ b/symposion/reviews/views.py
@@ -1,3 +1,5 @@
+import random
+
 from django.core.mail import send_mass_mail
 from django.db.models import Q
 from django.http import HttpResponseBadRequest, HttpResponseNotAllowed
@@ -103,6 +105,30 @@ def review_section(request, section_slug, assigned=False, reviewed="all"):
     return render(request, "symposion/reviews/review_list.html", ctx)
 
 
+@login_required
+def review_random_proposal(request, section_slug):
+    # lca2017 #16 view for random proposal
+
+    if not request.user.has_perm("reviews.can_review_%s" % section_slug):
+        return access_not_permitted(request)
+
+    section = get_object_or_404(ProposalSection, section__slug=section_slug)
+    queryset = ProposalBase.objects.filter(kind__section=section.section)
+    # Remove ones already reviewed
+    queryset = queryset.exclude(reviews__user=request.user)
+    # Remove talks the reviewer can't vote on -- their own.
+    queryset = queryset.exclude(speaker__user=request.user)
+    queryset = queryset.exclude(additional_speakers__user=request.user)
+
+    if len(queryset) == 0:
+        return redirect("review_section", section_slug=section_slug, reviewed="all")
+
+    # Realistically, there shouldn't be all that many proposals to choose
+    # from, so this should be cheap.
+    chosen = random.choice(queryset.all())
+    return redirect("review_detail", pk=chosen.pk)
+
+
 @login_required
 def review_list(request, section_slug, user_pk):
 
@@ -124,7 +150,7 @@ def review_list(request, section_slug, user_pk):
     ctx = {
         "proposals": proposals,
     }
-    return render(request, "symposion/reviews/review_list.html", ctx)
+    return (request, "symposion/reviews/review_list.html", ctx)
 
 
 @login_required