diff --git a/README.rst b/README.rst index 68fa783..206481e 100644 --- a/README.rst +++ b/README.rst @@ -72,6 +72,9 @@ The following apps are optional but will enhance the user experience: * The 'login su' form will render using `django-form-admin`_ * The user selection widget will render using `django-ajax-selects`_ +* The user selection widget will render using `django-autocomplete-light`_ + +`django-autocomplete-light`_ and `django-ajax-selects`_ are mutually exclusive. Note that `django-ajax-selects`_ requires the following settings: @@ -79,6 +82,41 @@ Note that `django-ajax-selects`_ requires the following settings: AJAX_LOOKUP_CHANNELS = {'django_su': dict(model='auth.user', search_field='username')} +`django-autocomplete-light`_ requires the following configuration: + +.. code-block:: python + + # settings.py + # this setting will be used to find the named url for the autocomplete view + SU_DAL_VIEW_NAME = 'user-autocomplete' + + # views.py + # we need an autocomplete view + from dal import autocomplete + from django.contrib.auth.models import User + + class UserAutoComplete(autocomplete.Select2QuerySetView): + def get_queryset(self): + user = self.request.user + qs = User.objects.none() + if user.is_authenticated and user.is_staff: + qs = User.objects.filter(username__icontains=self.q) + + return qs.order_by('pk') + + # urls.py + from .views import UserAutoComplete + from django.conf.urls import url + from django.conf import settings + + urlpatterns = [ + #... + url(r'^user-autocomplete/$', + UserAutoComplete.as_view(), + name=settings.SU_DAL_VIEW_NAME + ) + #.... + ] Configuration (optional) ------------------------ @@ -174,4 +212,5 @@ django-su is packaged using seed_. .. _django-form-admin: http://pypi.python.org/pypi/django-form-admin .. _django-ajax-selects: http://pypi.python.org/pypi/django-ajax-selects +.. _django-autocomplete-light: https://pypi.org/project/django-autocomplete-light/ .. _seed: https://github.com/adamcharnock/seed/ diff --git a/django_su/forms.py b/django_su/forms.py index 706b903..92d692d 100644 --- a/django_su/forms.py +++ b/django_su/forms.py @@ -53,3 +53,24 @@ def __str__(self): except ImportError: pass return super(UserSuForm, self).__str__() + + +class UserSuDalForm(UserSuForm): + def __init__(self, *args, **kwargs): + super(UserSuForm, self).__init__(*args, **kwargs) + + if "dal" in settings.INSTALLED_APPS and getattr( + settings, "SU_DAL_VIEW_NAME", None + ): + try: + from dal import autocomplete + except ImportError: + return + old_field = self.fields["user"] + + self.fields["user"] = forms.ModelChoiceField( + required=old_field.required, + label=old_field.label, + queryset=old_field.queryset, + widget=autocomplete.ModelSelect2(url=settings.SU_DAL_VIEW_NAME), + ) diff --git a/django_su/views.py b/django_su/views.py index 1293232..739bb9b 100644 --- a/django_su/views.py +++ b/django_su/views.py @@ -16,7 +16,7 @@ from django.views.decorators.csrf import csrf_protect from django.views.decorators.http import require_http_methods -from .forms import UserSuForm +from .forms import UserSuDalForm, UserSuForm from .utils import custom_login_action, su_login_callback @@ -61,7 +61,13 @@ def login_as_user(request, user_id): @csrf_protect @require_http_methods(["POST", "GET"]) @user_passes_test(su_login_callback) -def su_login(request, form_class=UserSuForm, template_name="su/login.html"): +def su_login(request, form_class=None, template_name="su/login.html"): + if form_class is None: + if getattr(settings, "SU_DAL_VIEW_NAME", None): + form_class = UserSuDalForm + else: + form_class = UserSuForm + form = form_class(request.POST or None) if form.is_valid(): return login_as_user(request, form.get_user().pk)