Skip to content

Commit

Permalink
add integration with django-autocomplete-light with UserSuDalForm
Browse files Browse the repository at this point in the history
adds UserSuDalForm form class which leverages the autocomplete
facilities provided by django-autocomplete-light.
It expects:
  * 'django-light-autocomplete' to be installed
  * 'dal' to be present into INSTALLED_APPS
  * 'SU_DAL_VIEW_NAME' setting to contain the name of the autocomplete view

If 'SU_DAL_VIEW_NAME' setting key is present and form_class is default su_login view tries to
automatically use UserSuDalForm, avoiding the end user to customize
django_su's urls.

Required configuration is added into README
  • Loading branch information
MRoci committed Apr 21, 2023
1 parent aadabf6 commit 8b7394c
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 2 deletions.
39 changes: 39 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,51 @@ 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:

.. code-block:: python
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)
------------------------
Expand Down Expand Up @@ -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/
21 changes: 21 additions & 0 deletions django_su/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
)
10 changes: 8 additions & 2 deletions django_su/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 8b7394c

Please sign in to comment.