We have so many users now that loading these forms take forever.
Instead, implement a textbox with autocomplete using django-selectable,
which will not load the whole list of users at once.
+from django import forms
from django.contrib import admin
+
+from selectable.forms.widgets import AutoCompleteSelectWidget
+
+from pgweb.core.lookups import UserLookup
+
from models import Contributor, ContributorType
+class ContributorAdminForm(forms.ModelForm):
+ class Meta:
+ model = Contributor
+ exclude = ()
+ widgets = {
+ 'user': AutoCompleteSelectWidget(lookup_class=UserLookup),
+ }
+
+ def __init__(self, *args, **kwargs):
+ super(ContributorAdminForm, self).__init__(*args, **kwargs)
+ self.fields['user'].widget.can_add_related = False
+ self.fields['user'].widget.can_change_related = False
+
+class ContributorAdmin(admin.ModelAdmin):
+ form = ContributorAdminForm
+
admin.site.register(ContributorType)
-admin.site.register(Contributor)
+admin.site.register(Contributor, ContributorAdmin)
+from django import forms
from django.contrib import admin
+from selectable.forms.widgets import AutoCompleteSelectMultipleWidget
+
from pgweb.core.models import Version, OrganisationType, Organisation
from pgweb.core.models import ImportedRSSFeed, ImportedRSSItem
from pgweb.core.models import ModerationNotification
+from pgweb.core.lookups import UserLookup
+
+class OrganisationAdminForm(forms.ModelForm):
+ class Meta:
+ model = Organisation
+ exclude = ()
+ widgets = {
+ 'managers': AutoCompleteSelectMultipleWidget(lookup_class=UserLookup),
+ }
+
+ def __init__(self, *args, **kwargs):
+ super(OrganisationAdminForm, self).__init__(*args, **kwargs)
+ self.fields['managers'].widget.can_add_related = False
+ self.fields['managers'].widget.can_change_related = False
+ self.fields['managers'].widget.can_delete_related = False
+
class OrganisationAdmin(admin.ModelAdmin):
+ form = OrganisationAdminForm
list_display = ('name', 'approved', 'lastconfirmed',)
list_filter = ('approved',)
ordering = ('name', )
- filter_horizontal = ('managers', )
search_fields = ('name', )
class VersionAdmin(admin.ModelAdmin):
--- /dev/null
+from django.contrib.auth.models import User
+from selectable.base import ModelLookup
+from selectable.registry import registry
+from selectable.decorators import staff_member_required
+
+
+@staff_member_required
+class UserLookup(ModelLookup):
+ model = User
+ search_fields = (
+ 'username__icontains',
+ 'first_name__icontains',
+ 'last_name__icontains',
+ )
+ filters = {'is_active': True, }
+
+ def get_item_value(self, item):
+ # Display for currently selected item
+ return u"%s (%s)" % (item.username, item.get_full_name())
+
+ def get_item_label(self, item):
+ # Display for choice listings
+ return u"%s (%s)" % (item.username, item.get_full_name())
+
+registry.register(UserLookup)
'django.contrib.admin',
'django_markwhat',
'django.contrib.staticfiles',
+ 'pgweb.selectable',
'pgweb.core',
'pgweb.mailqueue',
'pgweb.account',
# Uncomment the next line to enable the admin:
(r'^admin/', include(admin.site.urls)),
+ # We use selectable...
+ (r'^selectable/', include('selectable.urls')),
+
# This should not happen in production - serve by the webserver natively!
url(r'^(favicon.ico)$', 'django.views.static.serve', {
'document_root': 'media',
{%extends "admin/base.html"%}
{%block branding%}Welcome to the PostgreSQL website administration site | <b><a href="/admin/pending/">Pending</a></b> moderation | <b><a href="/admin/purge/">Purge</a></b> from frontend{%endblock%}
+
+{%block extrahead%}
+<link rel="stylesheet" href="/media/css/jquery-ui.css" type="text/css">
+<link href="/media/selectable/css/dj.selectable.css" type="text/css" media="all" rel="stylesheet">
+<script src="/media/js/jquery.min.js"></script>
+<script src="/media/js/jquery-ui.min.js"></script>
+<script type="text/javascript" src="/media/selectable/js/jquery.dj.selectable.js"></script>
+<style>
+ul.selectable-deck li.selectable-deck-item a.selectable-deck-remove {
+ float: none;
+ margin-left: 10px;
+}
+</style>
+{%endblock%}