changeset 149:ab7830b067b3

Implement ticket #40. Added a simple way to search for usernames and then view their profile. Moved this ajax username search feature out of the messages app and into core.
author Brian Neal <bgneal@gmail.com>
date Mon, 14 Dec 2009 05:07:28 +0000
parents 35a0e6345815
children b43e1288ff80
files gpp/bio/forms.py gpp/bio/urls.py gpp/bio/views.py gpp/core/urls.py gpp/core/views.py gpp/core/widgets.py gpp/messages/urls.py gpp/messages/views.py gpp/templates/bio/member_search.html gpp/templates/bio/members.html
diffstat 10 files changed, 80 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/gpp/bio/forms.py	Sun Dec 13 21:57:34 2009 +0000
+++ b/gpp/bio/forms.py	Mon Dec 14 05:07:28 2009 +0000
@@ -15,6 +15,7 @@
 from django.contrib.auth.models import User
 
 from bio.models import UserProfile
+from core.widgets import AutoCompleteUserInput
 
 
 class EditUserForm(forms.ModelForm):
@@ -112,3 +113,17 @@
     def get_filename(self):
         return self.cleaned_data['avatar_file'].name
 
+
+class SearchUsersForm(forms.Form):
+    """
+    A form to search for users.
+    """
+    username = forms.CharField(max_length=30, widget=AutoCompleteUserInput())
+
+    def clean_username(self):
+      username = self.cleaned_data['username']
+      try:
+         User.objects.get(username=username, is_active=True)
+      except User.DoesNotExist:
+         raise forms.ValidationError("That username does not exist.")
+      return username
--- a/gpp/bio/urls.py	Sun Dec 13 21:57:34 2009 +0000
+++ b/gpp/bio/urls.py	Mon Dec 14 05:07:28 2009 +0000
@@ -5,6 +5,7 @@
     url(r'^members/(?P<type>user|date)/page/(?P<page>\d+)/$', 
         'member_list', 
         name='bio-members_full'),
+    url(r'^members/search/$', 'member_search', name='bio-member_search'),
     url(r'^me/$', 'my_profile', name='bio-me'),
     url(r'^view/(?P<username>\w{1,30})/$', 'view_profile', name='bio-view_profile'),
     url(r'^edit/$', 'edit_profile', name='bio-edit_profile'),
--- a/gpp/bio/views.py	Sun Dec 13 21:57:34 2009 +0000
+++ b/gpp/bio/views.py	Mon Dec 14 05:07:28 2009 +0000
@@ -23,6 +23,7 @@
 from bio.forms import UploadAvatarForm
 from bio.forms import EditUserForm
 from bio.forms import EditUserProfileForm
+from bio.forms import SearchUsersForm
 from core.paginator import DiggPaginator
 from core.functions import email_admins
 
@@ -240,3 +241,21 @@
         }, 
         context_instance=RequestContext(request))
 
+#######################################################################
+
+@login_required
+def member_search(request):
+    if request.method == "POST":
+        form = SearchUsersForm(request.POST)
+        if form.is_valid():
+            username = form.cleaned_data['username']
+            return HttpResponseRedirect(reverse("bio-view_profile", 
+                kwargs={'username': username}))
+    else:
+        form = SearchUsersForm()
+
+    return render_to_response('bio/member_search.html', {
+        'form': form,
+        }, 
+        context_instance=RequestContext(request))
+
--- a/gpp/core/urls.py	Sun Dec 13 21:57:34 2009 +0000
+++ b/gpp/core/urls.py	Mon Dec 14 05:07:28 2009 +0000
@@ -5,4 +5,5 @@
 
 urlpatterns = patterns('core.views',
     url(r'^markdown_help/$', 'markdown_help', name='core-markdown_help'),
+    url(r'^ajax/users/$', 'ajax_users', name='core-ajax_users'),
 )
--- a/gpp/core/views.py	Sun Dec 13 21:57:34 2009 +0000
+++ b/gpp/core/views.py	Mon Dec 14 05:07:28 2009 +0000
@@ -2,6 +2,10 @@
 Views for the core application. These are mainly shared, common views
 used by multiple applications.
 """
+from django.contrib.auth.models import User
+from django.http import HttpResponse
+from django.http import HttpResponseBadRequest
+from django.http import HttpResponseForbidden
 from django.shortcuts import render_to_response
 from django.template import RequestContext
 from django.contrib.auth.decorators import login_required
@@ -15,3 +19,24 @@
     to be called via AJAX.
     """
     return render_to_response('core/markdown_help.html')
+
+
+def ajax_users(request):
+    """
+    If the user is authenticated, return a string of usernames whose names start with
+    the 'q' GET parameter, limited by the 'limit' GET parameters. The names are separated
+    by newlines. Only active usernames are returned.
+    If the user is not authenticated, return an empty string.
+    """
+    q = request.GET.get('q', None)
+    if q is None:
+        return HttpResponseBadRequest()
+
+    if request.user.is_authenticated():
+        q = request.GET.get('q', ' ')
+        limit = int(request.GET.get('limit', 10))
+        users = User.objects.filter(is_active=True, 
+                username__istartswith=q).values_list('username', flat=True)[:limit]
+        user_list = u"\n".join(users)
+        return HttpResponse(user_list)
+    return HttpResponseForbidden()
--- a/gpp/core/widgets.py	Sun Dec 13 21:57:34 2009 +0000
+++ b/gpp/core/widgets.py	Mon Dec 14 05:07:28 2009 +0000
@@ -16,7 +16,7 @@
         js = settings.GPP_THIRD_PARTY_JS['jquery-autocomplete']
 
     def render(self, name, value, attrs=None):
-        url = reverse('messages-ajax_users')
+        url = reverse('core-ajax_users')
         output = super(AutoCompleteUserInput, self).render(name, value, attrs)
         return output + mark_safe(u'''\
 <script type="text/javascript">
--- a/gpp/messages/urls.py	Sun Dec 13 21:57:34 2009 +0000
+++ b/gpp/messages/urls.py	Mon Dec 14 05:07:28 2009 +0000
@@ -14,7 +14,6 @@
     url(r'^undelete/$', 'undelete_bulk', name='messages-undelete_bulk'),
     url(r'^undelete/(\d+)/$', 'undelete', name='messages-undelete'),
     url(r'^options/$', 'options', name='messages-options'),
-    url(r'^ajax/users/$', 'ajax_users', name='messages-ajax_users'),
 )
 
 urlpatterns += patterns('django.views.generic.simple',
--- a/gpp/messages/views.py	Sun Dec 13 21:57:34 2009 +0000
+++ b/gpp/messages/views.py	Mon Dec 14 05:07:28 2009 +0000
@@ -3,11 +3,7 @@
 import datetime
 from django.shortcuts import render_to_response
 from django.template import RequestContext
-from django.contrib.auth.models import User
 from django.http import HttpResponseRedirect
-from django.http import HttpResponse
-from django.http import HttpResponseBadRequest
-from django.http import HttpResponseForbidden
 from django.contrib.auth.decorators import login_required
 from django.shortcuts import get_object_or_404
 from django.core.urlresolvers import reverse
@@ -285,26 +281,3 @@
         }, 
         context_instance = RequestContext(request))
 
-
-def ajax_users(request):
-    """
-    If the user is authenticated, return a string of usernames whose names start with
-    the 'q' GET parameter, limited by the 'limit' GET parameters. The names are separated
-    by newlines.
-    If the user is not authenticated, return an empty string.
-    This is used by the auto-complete function in the compose form.
-    """
-    q = request.GET.get('q', None)
-    if q is None:
-        return HttpResponseBadRequest()
-
-    if request.user.is_authenticated():
-        q = request.GET.get('q', ' ')
-        limit = int(request.GET.get('limit', 10))
-        users = User.objects.filter(username__istartswith=q).values_list('username', flat=True)[:limit]
-        user_list = u"\n".join(users)
-        return HttpResponse(user_list)
-    return HttpResponseForbidden()
-
-
-# vim: ts=4 sw=4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gpp/templates/bio/member_search.html	Mon Dec 14 05:07:28 2009 +0000
@@ -0,0 +1,16 @@
+{% extends "base.html" %}
+{% block title %}Member Search{% endblock %}
+{% block custom_js %}
+   {{ form.media }}
+{% endblock %}
+{% block content %}
+<h2>Member Search</h2>
+<p>Looking for a member? Start typing a username in the form below.</p>
+<form action="." method="post">
+<fieldset>
+<legend>Member Search</legend>
+   {{ form.as_p }}
+   <p><input type="submit" value="View Profile" /></p>
+</fieldset>
+</form>
+{% endblock %}
--- a/gpp/templates/bio/members.html	Sun Dec 13 21:57:34 2009 +0000
+++ b/gpp/templates/bio/members.html	Mon Dec 14 05:07:28 2009 +0000
@@ -7,7 +7,8 @@
 {% endblock %}
 {% block content %}
 <h2>Member List</h2>
-<p>Surfguitar101.com currently has {{ num_members }} active members.</p>
+<p>Surfguitar101.com currently has {{ num_members }} active members. Looking for a
+particular user? Try our <a href="{% url bio-member_search %}">member search</a>.</p>
 {% if page.object_list %}
 <ul class="tab-nav">
    <li><a href="{% url bio-members_full type="user",page="1" %}"